alex af15e0698b Codebase
git-svn-id: svn://10.65.10.50/trunk@4679 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-06-16 13:01:08 +00:00

208 lines
4.9 KiB
C
Executable File

/* 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 */