208 lines
4.7 KiB
C
208 lines
4.7 KiB
C
|
/* c4bcd.c (c)Copyright Sequiter Software Inc., 1990-1994. All rights reserved. */
|
||
|
/* binary digit is: xxxx xxxx xxxx xx01 */
|
||
|
/* sig dig |||| |||| */
|
||
|
/* |||| ||always 01 */
|
||
|
/* |length */
|
||
|
/* sign */
|
||
|
|
||
|
#include "d4all.h"
|
||
|
#ifndef S4UNIX
|
||
|
#ifdef __TURBOC__
|
||
|
#pragma hdrstop
|
||
|
#endif /* __TUROBC__ */
|
||
|
#endif /* S4UNIX */
|
||
|
|
||
|
#ifdef S4MDX
|
||
|
|
||
|
/* MDX */
|
||
|
int S4CALL c4bcd_cmp( S4CMP_PARM a_ptr, S4CMP_PARM b_ptr, size_t dummy_len )
|
||
|
{
|
||
|
int a_sign, b_sign, a_len, b_len, a_sig_dig, b_sig_dig, compare_len, rc ;
|
||
|
|
||
|
if ( ((C4BCD *)a_ptr)->digit_info & 0x80 ) /* get digit sign */
|
||
|
a_sign = -1 ;
|
||
|
else
|
||
|
a_sign = 1 ;
|
||
|
|
||
|
if ( ((C4BCD *)b_ptr)->digit_info & 0x80 )
|
||
|
b_sign = -1 ;
|
||
|
else
|
||
|
b_sign = 1 ;
|
||
|
|
||
|
if ( a_sign != b_sign )
|
||
|
return a_sign ;
|
||
|
|
||
|
a_len = ( (((C4BCD *)a_ptr)->digit_info >> 2) & 0x1F ) ; /* get digit length */
|
||
|
b_len = ( (((C4BCD *)b_ptr)->digit_info >> 2) & 0x1F ) ;
|
||
|
|
||
|
if ( a_len == 0 )
|
||
|
a_sig_dig = 0 ;
|
||
|
else
|
||
|
a_sig_dig = ((C4BCD *)a_ptr)->sig_dig ; /* get digit significant digit */
|
||
|
|
||
|
if ( b_len == 0 )
|
||
|
b_sig_dig = 0 ;
|
||
|
else
|
||
|
b_sig_dig = ((C4BCD *)b_ptr)->sig_dig ;
|
||
|
|
||
|
if ( a_sig_dig != b_sig_dig )
|
||
|
{
|
||
|
if ( a_sig_dig < b_sig_dig )
|
||
|
return -a_sign ;
|
||
|
else
|
||
|
return a_sign ;
|
||
|
}
|
||
|
|
||
|
compare_len = (a_len < b_len) ? b_len : a_len ; /* Use Max */
|
||
|
|
||
|
compare_len = (compare_len+1)/2 ;
|
||
|
|
||
|
rc = c4memcmp( ((C4BCD *)a_ptr)->bcd, ((C4BCD *)b_ptr)->bcd, compare_len ) ;
|
||
|
if ( a_sign < 0 ) return -rc ;
|
||
|
|
||
|
return rc ;
|
||
|
}
|
||
|
|
||
|
/* MDX */
|
||
|
void c4bcd_from_a( char *result, char *input_ptr, int input_ptr_len )
|
||
|
{
|
||
|
char *ptr ;
|
||
|
unsigned len ;
|
||
|
int n, last_pos, pos, is_before_dec, zero_count ;
|
||
|
|
||
|
memset( result, 0, sizeof(C4BCD) ) ;
|
||
|
|
||
|
last_pos = input_ptr_len - 1 ;
|
||
|
pos = 0 ;
|
||
|
for ( ; pos <= last_pos; pos++ )
|
||
|
if ( input_ptr[pos] != ' ' ) break ;
|
||
|
|
||
|
if ( pos <= last_pos )
|
||
|
{
|
||
|
if ( input_ptr[pos] == '-' )
|
||
|
{
|
||
|
((C4BCD *)result)->digit_info=(unsigned char)((int)((C4BCD *)result)->digit_info | 0x80) ;
|
||
|
pos++ ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( input_ptr[pos] == '+' ) pos++ ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for ( ; pos <= last_pos; pos++ )
|
||
|
if ( input_ptr[pos] != ' ' && input_ptr[pos] != '0' ) break ;
|
||
|
|
||
|
is_before_dec = 1 ;
|
||
|
|
||
|
((C4BCD *)result)->sig_dig = 0x34 ;
|
||
|
if ( pos <= last_pos )
|
||
|
if ( input_ptr[pos] == '.' )
|
||
|
{
|
||
|
is_before_dec = 0 ;
|
||
|
pos++ ;
|
||
|
for ( ; pos <= last_pos; pos++ )
|
||
|
{
|
||
|
if ( input_ptr[pos] != '0' ) break ;
|
||
|
((C4BCD *)result)->sig_dig-- ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ptr = (char *) ((C4BCD *)result)->bcd ; ;
|
||
|
zero_count = 0 ;
|
||
|
|
||
|
for ( n=0; pos <= last_pos; pos++ )
|
||
|
{
|
||
|
if ( input_ptr[pos] >= '0' && input_ptr[pos] <= '9' )
|
||
|
{
|
||
|
if ( input_ptr[pos] == '0' )
|
||
|
zero_count++ ;
|
||
|
else
|
||
|
zero_count = 0 ;
|
||
|
if ( n >= 20 ) break ;
|
||
|
if ( n & 1 )
|
||
|
*ptr++ |= input_ptr[pos] - '0' ;
|
||
|
else
|
||
|
*ptr += (unsigned char)( (unsigned char)((unsigned char)input_ptr[pos] - (unsigned char)'0') << 4 ) ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( input_ptr[pos] != '.' || ! is_before_dec )
|
||
|
break ;
|
||
|
|
||
|
is_before_dec = 0 ;
|
||
|
continue ;
|
||
|
}
|
||
|
if ( is_before_dec )
|
||
|
((C4BCD *)result)->sig_dig++ ;
|
||
|
|
||
|
n++ ;
|
||
|
}
|
||
|
/* 'always one' bit filled */
|
||
|
((C4BCD *)result)->digit_info = (unsigned char)( ((C4BCD *)result)->digit_info | 0x1 ) ;
|
||
|
|
||
|
#ifdef S4DEBUG
|
||
|
if ( n - zero_count < 0 )
|
||
|
e4severe( e4info, E4_C4BCD_FROM_A ) ;
|
||
|
#endif
|
||
|
|
||
|
len = n - zero_count ;
|
||
|
if (len > 31)
|
||
|
len = 31 ;
|
||
|
|
||
|
((C4BCD *)result)->digit_info = (unsigned char)( ((C4BCD *)result)->digit_info | (len << 2) ) ;
|
||
|
|
||
|
if ( len == 0 )
|
||
|
((C4BCD *)result)->digit_info = (unsigned char)( ((C4BCD *)result)->digit_info & 0x7F ) ;
|
||
|
}
|
||
|
|
||
|
/* MDX */
|
||
|
void c4bcd_from_d( char *result, double doub )
|
||
|
{
|
||
|
char temp_str[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 ;
|
||
|
temp_str[0] = '-' ;
|
||
|
}
|
||
|
else
|
||
|
pos = 0 ;
|
||
|
|
||
|
if ( dec < 0 )
|
||
|
{
|
||
|
dec = -dec ;
|
||
|
len = dec+1+pos ;
|
||
|
memcpy( temp_str+len, ptr, E4ACCURACY_DIGITS ) ;
|
||
|
memset( temp_str+pos, '0', len-pos ) ;
|
||
|
temp_str[pos] = '.' ;
|
||
|
|
||
|
c4bcd_from_a( result, temp_str, E4ACCURACY_DIGITS + len ) ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
memcpy( temp_str+pos, ptr, dec ) ;
|
||
|
pos += dec ;
|
||
|
if ( dec < E4ACCURACY_DIGITS )
|
||
|
{
|
||
|
temp_str[pos++] = '.' ;
|
||
|
|
||
|
len = E4ACCURACY_DIGITS - dec ;
|
||
|
memcpy( temp_str+pos, ptr+dec, len ) ;
|
||
|
pos += len ;
|
||
|
}
|
||
|
c4bcd_from_a( result, temp_str, pos ) ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif /* S4MDX */
|
||
|
|
||
|
|