Example #1
0
C_MODE_END

inline int my_decimal_get_binary_size(uint precision, uint scale)
{
  return decimal_bin_size((int)precision, (int)scale);
}
Example #2
0
int bin2dec(const char *from, decimal_t *to, int precision, int scale)
{
    int error=E_DEC_OK, intg=precision-scale,
            intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
            intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1,
            intg1=intg0+(intg0x>0), frac1=frac0+(frac0x>0);
    dec1 *buf=to->buf, mask=(*from & 0x80) ? 0 : -1;
    const char *stop;
    char *d_copy;
    int bin_size= decimal_bin_size(precision, scale);

    //sanity(to);
    d_copy= (char*) my_alloca(bin_size);
    memcpy(d_copy, from, bin_size);
    d_copy[0]^= 0x80;
    from= d_copy;

    FIX_INTG_FRAC_ERROR(to->len, intg1, frac1, error);
    if (unlikely(error))
    {
        if (intg1 < intg0+(intg0x>0))
        {
            from+=dig2bytes[intg0x]+sizeof(dec1)*(intg0-intg1);
            frac0=frac0x=intg0x=0;
            intg0=intg1;
        }
        else
        {
            frac0x=0;
            frac0=frac1;
        }
    }

    to->sign=(mask != 0);
    to->intg=intg0*DIG_PER_DEC1+intg0x;
    to->frac=frac0*DIG_PER_DEC1+frac0x;

    if (intg0x)
    {
        int i=dig2bytes[intg0x];
        dec1 UNINIT_VAR(x);
        switch (i)
        {
            case 1: x=mi_sint1korr(from); break;
            case 2: x=mi_sint2korr(from); break;
            case 3: x=mi_sint3korr(from); break;
            case 4: x=mi_sint4korr(from); break;
            default: DBUG_ASSERT(0);
        }
        from+=i;
        *buf=x ^ mask;
        if (((ulonglong)*buf) >= (ulonglong) powers10[intg0x+1])
            goto err;
        if (buf > to->buf || *buf != 0)
            buf++;
        else
            to->intg-=intg0x;
    }
    for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1))
    {
        DBUG_ASSERT(sizeof(dec1) == 4);
        *buf=mi_sint4korr(from) ^ mask;
        if (((uint32)*buf) > DIG_MAX)
            goto err;
        if (buf > to->buf || *buf != 0)
            buf++;
        else
            to->intg-=DIG_PER_DEC1;
    }
    DBUG_ASSERT(to->intg >=0);
    for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1))
    {
        DBUG_ASSERT(sizeof(dec1) == 4);
        *buf=mi_sint4korr(from) ^ mask;
        if (((uint32)*buf) > DIG_MAX)
            goto err;
        buf++;
    }
    if (frac0x)
    {
        int i=dig2bytes[frac0x];
        dec1 UNINIT_VAR(x);
        switch (i)
        {
            case 1: x=mi_sint1korr(from); break;
            case 2: x=mi_sint2korr(from); break;
            case 3: x=mi_sint3korr(from); break;
            case 4: x=mi_sint4korr(from); break;
            default: DBUG_ASSERT(0);
        }
        *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
        if (((uint32)*buf) > DIG_MAX)
            goto err;
        buf++;
    }
    my_afree(d_copy);

    if (to->intg == 0 && to->frac == 0)
        decimal_make_zero(to);
    return error;

err:
    my_afree(d_copy);
    decimal_make_zero(to);
    return(E_DEC_BAD_NUM);
}