campo-sirio/cb5/c4bcd.c
alex a0f5e0898b This commit was generated by cvs2svn to compensate for changes in r975,
which included commits to RCS files with non-trunk default branches.

git-svn-id: svn://10.65.10.50/trunk@976 c028cbd2-c16b-5b4b-a496-9718f37d4682
1995-02-06 15:33:45 +00:00

208 lines
4.7 KiB
C
Executable File

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