Logo Search packages:      
Sourcecode: maxdb-7.5.00 version File versions

IFR_Retcode IFRUtil_SQLNumeric::numberToNumeric ( const unsigned char *  vdnnumber,
IFR_Int4  length,
SQL_NUMERIC_STRUCT number,
IFR_UInt1  precision 
) [static]

Converts a VDN Number to a SQL_NUMERIC_STRUCT.

Parameters:
vdnnumber The source VDN Number.
length The number of digits of the VDN number.
number The target SQL_NUMERIC_STRUCT.
precision The precision field of the SQL_NUMERIC_STRUCT.
Returns:
IFR_NOT_OK if the conversion fails, IFR_OK otherwise.

Definition at line 471 of file IFRUtil_SQLNumeric.cpp.

References IFR_OK, SQL_NUMERIC_STRUCT::precision, SQL_NUMERIC_STRUCT::scale, SQL_NUMERIC_STRUCT::sign, SQL_MAX_NUMERIC_LENGTH, and SQL_NUMERIC_STRUCT::val.

{
    memset(&number, 0, sizeof(SQL_NUMERIC_STRUCT));
    
    // at first we will check for zero
    if(*vdnnumber == 0x80) {
        // Create a +0 with the right precision.
        number.precision=precision;
        number.sign=1;
    }
    IFR_Int4 exponent = *vdnnumber;
    IFR_Int4 lastsignificant=0;
    // get the last zero
    for(IFR_Int4 i = 0; i<length; ++i) {
        if(i & 1) {
            if(vdnnumber[1 + i/2] & 0x0F) {
                lastsignificant = i;
            }
        } else {
            if(vdnnumber[1 + i/2] & 0xF0) {
                lastsignificant = i;
            }
        }
    }
    
    // we have handled up to lastsignificant + 1 digits 
    // the original number value was
    //
    //   value * pow(10, exponent); // 0 < value < 1
    // 
    // is same as
    //
    //   value * pow(10, numdigits) * pow(10, -numdigits) * pow(10, exponent)
    //
    // which eventually lead to setting the scale of the SQL_NUMERIC_STRUCT
    // to - (exponent - numdigits) = numdigits - exponents

    number.scale = lastsignificant + 1 - exponent;
    number.precision = precision;
    
    IFR_Int4   startDigit=0;
    IFR_UInt4  tmpRes=0;
    if(*vdnnumber < 0x80) {
        exponent = -exponent + 64;
               
        for(IFR_Int4 nByte=0; nByte<SQL_MAX_NUMERIC_LENGTH &&  (startDigit<length || tmpRes!=0); ++nByte) {
            int pos = length - 1 - startDigit;
            for(IFR_Int4 nDigit = startDigit; nDigit<length; nDigit ++) {
                IFR_Int4 currentDigit;
                if(pos < lastsignificant) {
                    if(pos & 1) {
                        currentDigit = 9 - (vdnnumber[1 + pos/2] & 0x0F);
                    } else {
                        currentDigit = 9 - (vdnnumber[1 + pos/2] >> 4);
                    }
                } else if(pos == lastsignificant) {
                    if(pos & 1) {
                        currentDigit = 10 - (vdnnumber[1 + pos/2] & 0x0F);
                    } else {
                        currentDigit = 10 - (vdnnumber[1 + pos/2] >> 4);
                    }
                } else { // behind the last significant number all
                    // is zero, we can stop
                    break;
                }
                tmpRes += currentDigit * string2integer_decfactors[nDigit][nByte];
                --pos;
            }
            number.val[nByte] = tmpRes & 0xFF;
            tmpRes >>= 8;
            startDigit = string2integer_startdigits[nByte+1];
        }
        
    } else {
        exponent -= 192;
        number.sign=1; // signal number > 0

        for(IFR_Int4 nByte=0; nByte<SQL_MAX_NUMERIC_LENGTH &&  (startDigit<length || tmpRes!=0); ++nByte) {
            int pos = length - 1 - startDigit;
            for(IFR_Int4 nDigit = startDigit; nDigit<length; nDigit ++) {
                IFR_Int4 currentDigit;
                if(pos <= lastsignificant) {
                    if(pos & 1) {
                        currentDigit = (vdnnumber[1 + pos/2] & 0x0F);
                    } else {
                        currentDigit = (vdnnumber[1 + pos/2] >> 4);
                    }
                } else { // behind the last significant number all
                    // is zero, we can stop
                    break;
                }
                tmpRes += currentDigit * string2integer_decfactors[nDigit][nByte];
                --pos;
            }
            number.val[nByte] = tmpRes & 0xFF;
            tmpRes >>= 8;
            startDigit = string2integer_startdigits[nByte+1];
        }
    }

    return IFR_OK;
}


Generated by  Doxygen 1.6.0   Back to index