208 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			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 */
 |