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