/* c4bcd.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */ /* binary digit is: xxxx xxxx xxxx xx01 */ /* sig dig |||| |||| */ /* |||| ||always 01 */ /* |length */ /* sign */ #include "d4all.h" #ifdef __TURBOC__ #pragma hdrstop #endif /* __TUROBC__ */ #ifdef S4MDX /* MDX */ int S4CALL c4bcdCmp( S4CMP_PARM aPtr, S4CMP_PARM bPtr, size_t dummyLen ) { int aSign, bSign, aLen, bLen, aSigDig, bSigDig, compareLen, rc ; if ( ((C4BCD *)aPtr)->digitInfo & 0x80 ) /* get digit sign */ aSign = -1 ; else aSign = 1 ; if ( ((C4BCD *)bPtr)->digitInfo & 0x80 ) bSign = -1 ; else bSign = 1 ; if ( aSign != bSign ) return aSign ; aLen = ( (((C4BCD *)aPtr)->digitInfo >> 2) & 0x1F ) ; /* get digit length */ bLen = ( (((C4BCD *)bPtr)->digitInfo >> 2) & 0x1F ) ; if ( aLen == 0 ) aSigDig = 0 ; else aSigDig = ((C4BCD *)aPtr)->sigDig ; /* get digit significant digit */ if ( bLen == 0 ) bSigDig = 0 ; else bSigDig = ((C4BCD *)bPtr)->sigDig ; if ( aSigDig != bSigDig ) { if ( aSigDig < bSigDig ) return -aSign ; else return aSign ; } compareLen = (aLen < bLen) ? bLen : aLen ; /* Use Max */ compareLen = (compareLen+1)/2 ; rc = c4memcmp( ((C4BCD *)aPtr)->bcd, ((C4BCD *)bPtr)->bcd, compareLen ) ; if ( aSign < 0 ) return -rc ; return rc ; } /* MDX */ void c4bcdFromA( char *result, const char *inputPtr, const int inputPtrLen ) { char *ptr ; unsigned len ; int n, lastPos, pos, isBeforeDec, zeroCount ; memset( result, 0, sizeof(C4BCD) ) ; lastPos = inputPtrLen - 1 ; pos = 0 ; for ( ; pos <= lastPos; pos++ ) if ( inputPtr[pos] != ' ' ) break ; if ( pos <= lastPos ) { if ( inputPtr[pos] == '-' ) { ((C4BCD *)result)->digitInfo=(unsigned char)((int)((C4BCD *)result)->digitInfo | 0x80) ; pos++ ; } else { if ( inputPtr[pos] == '+' ) pos++ ; } } for ( ; pos <= lastPos; pos++ ) if ( inputPtr[pos] != ' ' && inputPtr[pos] != '0' ) break ; isBeforeDec = 1 ; ((C4BCD *)result)->sigDig = 0x34 ; if ( pos <= lastPos ) if ( inputPtr[pos] == '.' ) { isBeforeDec = 0 ; pos++ ; for ( ; pos <= lastPos; pos++ ) { if ( inputPtr[pos] != '0' ) break ; ((C4BCD *)result)->sigDig-- ; } } ptr = (char *) ((C4BCD *)result)->bcd ; ; zeroCount = 0 ; for ( n=0; pos <= lastPos; pos++ ) { if ( inputPtr[pos] >= '0' && inputPtr[pos] <= '9' ) { if ( inputPtr[pos] == '0' ) zeroCount++ ; else zeroCount = 0 ; if ( n >= 20 ) break ; if ( n & 1 ) *ptr++ |= inputPtr[pos] - '0' ; else *ptr += (unsigned char)( (unsigned char)((unsigned char)inputPtr[pos] - (unsigned char)'0') << 4 ) ; } else { if ( inputPtr[pos] != '.' || ! isBeforeDec ) break ; isBeforeDec = 0 ; continue ; } if ( isBeforeDec ) ((C4BCD *)result)->sigDig++ ; n++ ; } /* 'always one' bit filled */ ((C4BCD *)result)->digitInfo = (unsigned char)( ((C4BCD *)result)->digitInfo | 0x1 ) ; #ifdef E4MISC if ( n - zeroCount < 0 ) { error4( 0, e4info, E95105 ) ; return ; } #endif len = n - zeroCount ; if (len > 31) len = 31 ; ((C4BCD *)result)->digitInfo = (unsigned char)( ((C4BCD *)result)->digitInfo | (len << 2) ) ; if ( len == 0 ) ((C4BCD *)result)->digitInfo = (unsigned char)( ((C4BCD *)result)->digitInfo & 0x7F ) ; } /* MDX */ void c4bcdFromD( char *result, const double doub ) { char tempStr[258], *ptr ; int sign, dec, len, pos ; #ifdef S4NO_ECVT ptr = f4ecvt( doub, E4ACCURACY_DIGITS, &dec, &sign ) ; #else ptr = ecvt( doub, E4ACCURACY_DIGITS, &dec, &sign ) ; #endif if ( sign ) { pos = 1 ; tempStr[0] = '-' ; } else pos = 0 ; if ( dec < 0 ) { dec = -dec ; len = dec+1+pos ; memcpy( tempStr+len, ptr, E4ACCURACY_DIGITS ) ; memset( tempStr+pos, '0', len-pos ) ; tempStr[pos] = '.' ; c4bcdFromA( result, tempStr, E4ACCURACY_DIGITS + len ) ; } else { memcpy( tempStr+pos, ptr, dec ) ; pos += dec ; if ( dec < E4ACCURACY_DIGITS ) { tempStr[pos++] = '.' ; len = E4ACCURACY_DIGITS - dec ; memcpy( tempStr+pos, ptr+dec, len ) ; pos += len ; } c4bcdFromA( result, tempStr, pos ) ; } } #endif /* S4MDX */