Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
//**************************************
//
//INCLUDE files for :BCD math (to/from d
// ouble) functions
//**************************************
//
/* +++Date last modified: 05-Jul-1997 */
/*
** SNIPMATH.H - Header file for SNIPPETS math functions and macros
*/
#ifndef SNIPMATH__H
#define SNIPMATH__H
#include
#include "sniptype.h"
#include "round.h"
/*
** Callable library functions begin here
*/
voidSetBCDLen(int n); /* Bcdl.C */
longBCDtoLong(char *BCDNum); /* Bcdl.C */
voidLongtoBCD(long num, char BCDNum[]);/* Bcdl.C */
double bcd_to_double(void *buf, size_t len, /* Bcdd.C */
int digits);
int double_to_bcd(double arg, char *buf, /* Bcdd.C */
size_t length, size_t digits );
DWORDncomb1 (int n, int m);/* Combin.C*/
DWORDncomb2 (int n, int m);/* Combin.C*/
voidSolveCubic(double a, double b, double c, /* Cubic.C*/
double d, int *solutions,
double *x);
DWORDdbl2ulong(double t); /* Dbl2Long.C */
longdbl2long(double t);/* Dbl2Long.C */
double dround(double x); /* Dblround.C */
/* Use #defines for Permutations and Combinations -- Factoryl.C */
#define log10P(n,r) (log10factorial(n)-log10factorial((n)-(r)))
#define log10C(n,r) (log10P((n),(r))-log10factorial(r))
double log10factorial(double N); /* Factoryl.C */
double fibo(unsigned short term);/* Fibo.C */
double frandom(int n);/* Frand.C*/
double ipow(double x, int n);/* Ipow.C */
int ispow2(int x);/* Ispow2.C*/
longdouble ldfloor(long double a);/* Ldfloor.C */
int initlogscale(long dmax, long rmax);/* Logscale.C */
longlogscale(long d); /* Logscale.C */
floatMSBINToIEEE(float f); /* Msb2Ieee.C */
floatIEEEToMSBIN(float f); /* Msb2Ieee.C */
int perm_index (char pit[], int size);/* Perm_Idx.C */
int round_div(int n, int d); /* Rnd_Div.C */
longround_ldiv(long n, long d);/* Rnd_Div.C */
double rad2deg(double rad); /* Rad2Deg.C */
double deg2rad(double deg); /* Rad2Deg.C */
#include "pi.h"
#ifndef PHI
#define PHI ((1.0+sqrt(5.0))/2.0) /* the golden number*/
#define INV_PHI (1.0/PHI) /* the golden ratio */
#endif
/*
** File: ISQRT.C
*/
struct int_sqrt {
unsigned sqrt,
frac;
};
void usqrt(unsigned long x, struct int_sqrt *q);
#endif /* SNIPMATH__H */
code:
Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
Terms of Agreement:
By using this code, you agree to the following terms...
1) You may use this code in your own programs (and may compile it into a program and distribute it in compiled format for langauges that allow it) freely and with no charge.
2) You MAY NOT redistribute this code (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
3) You may link to this code from another website, but ONLY if it is not wrapped in a frame.
4) You will abide by any additional copyright restrictions which the author may have placed in the code or code's description.
*/
/* File Id:bcd.c. */
/* Author: Stan Milam.*/
/* Date Written:31-Jan-95. */
/* Description:*/
/* Routines to manage binary coded decimal.*/
/**/
/* bcd_to_double() - Convert BCD to type double value.*/
/* double_to_bcd() - Convert double type value to BCD.*/
/**/
/* Placed in the public domain by the author, 8-Sep-95*/
/**/
/*****************************************************************FILE*/
#include
#include
#include
#include
#include
#include "snipmath.h"
/*FUNCTION*************************************************************/
/* Name: bcd_to_double(). */
/**/
/* Description:*/
/* this function will convert buffer containing binary coded dec- */
/* imal to a double. */
/**/
/* Arguments: */
/* void *buf - Address of buffer containing binary coded */
/* decimal number.*/
/* size_tbuflen- Length of the buffer. */
/* int digits- The number of digits to the right of the */
/* decimal point.*/
/**/
/* return Value: */
/* A value of type double which should be the equivalent of the*/
/* BCD value. */
/**/
/**********************************************************************/
double bcd_to_double(void *buf, size_t len, int digits)
{
doublerv = 0.0;
char *buffer = (char *) buf;
size_thigh, low, index, max = len - 1;
digits = abs(digits);
/******************************************************************/
/* Loop through the buffer repeatedly extracting the high and low */
/* 4 bits from each byte and calculating the return value.*/
/******************************************************************/
for (index = 0; index < max; index++)
{
low = buffer[index] & 0x0f;
high = (buffer[index] & 0xf0) >> 4;
rv = (( rv * 10.0 + high ) * 10.0 + low);
}
/******************************************************************/
/* The first byte of the buffer contains the lowest order digit*/
/* in the upper 4 bits and the sign in the lower 4 bits. */
/******************************************************************/
low = buffer[max] & 0x0f;
high = (buffer[max] & 0xf0) >> 4;
rv = rv * 10.0 + high;
if (digits > 0)
rv /= pow(10, digits);
if (low == 0x0d)
rv = -rv;
return rv;
}
/*FUNCTION*************************************************************/
/* Name: double_to_bcd(). */
/**/
/* Description:*/
/* this function will convert a value of type double to a legit- */
/* mate Binary Coded Decimal (BCD) value. */
/**/
/* Arguments: */
/* doublearg- The value to be converted.*/
/* char *buf- The buffer where the BCD value is stored.*/
/* size_tlength - The number of significant digits to store in */
/*BCD buffer. */
/* size_tdigits - The number of digits to the right of the */
/*decimal point to be stored in the BCD*/
/*buffer. */
/**/
/* return Value: */
/* An integer value indicating the length of the BCD value in the */
/* buffer. -1 is returned if an error occured.*/
/**/
/*************************************************************FUNCTION*/
int double_to_bcd(double arg, char *buf, size_t length, size_t digits )
{
char wrkbuf[50], format[DBL_DIG + 1];
int y_sub, x_sub, rv, negative=0;
/******************************************************************/
/* do a couple of sanity checks first.*/
/******************************************************************/
if ((length == 0 && digits == 0) || (length + digits > DBL_DIG))
rv = -1;
else
{
/**************************************************************/
/* if the double argument is negative make a note of it and*/
/* con- vert the value to be positive.*/
/**************************************************************/
if (arg < 0.0)
{
arg = -arg;
negative = 1;
}
/**************************************************************/
/* Adjust for decimal digits. */
/**************************************************************/
if (digits > 0)
{
length += digits;
arg *= pow( 10, digits );
}
/**************************************************************/
/* Build the format string, build the string and compute the */
/* return value. */
/**************************************************************/
sprintf( format, "%%0%d.0f", length );
sprintf( wrkbuf, format, floor( arg ) );
if ((rv = (length / 2 ) + (length / 2 != 0)) == 0)
rv = 1;
/**************************************************************/
/* Compute the subscript values and clear the BCD buffer. */
/**************************************************************/
y_sub = rv - 1;
x_sub = strlen( wrkbuf ) - 1;
memset( buf, 0, y_sub + 1 );
/**************************************************************/
/* Plug in the sign bits and first BCD digit. */
/**************************************************************/
buf[y_sub] = negative == 1 ? 0xd : 0xc;
buf[y_sub--] |= ( ( wrkbuf[x_sub--] - '0' ) << 4 );
/**************************************************************/
/* while we have more digits to plug.... */
/**************************************************************/
while ( --length > 0 )
{
/**********************************************************/
/* do the low nibble of the BCD byte. */
/**********************************************************/
buf[y_sub] = wrkbuf[x_sub--] - '0';
if (--length <= 0)
break;
/**********************************************************/
/* Now do the high nibble.*/
/**********************************************************/
buf[y_sub--] |= ((wrkbuf[x_sub--] - '0') << 4);
}
}
return rv;
}
/**/
#ifdef TEST
typedef struct {
double value, expect;
intlength, digits;
} TEST_T;
int main(void)
{
double rv, value;
charwrkbf[25];
intrc, x_sub, y_sub, size, len, digits;
charformat[] = "%10.3f %d %d%d ";
TEST_T testvals[] = {
{ 12345.67, 123.45,5, 0 },
{ 12345.67,12345.0,5, 1 },
{ 12345.67,12345.67, 4, 3 },
{ 12345.678,2345.67, 1, 2 },
{ -12345.00, -12345.00, 8, 2 },
{ -1234.56, -12345.00,5, 3 },
{ 1234.567, 0.60,1, 3 }
};
size = sizeof( testvals ) / sizeof( TEST_T );
printf("DoubleLength DigitsReturn\n");
printf("Argument ArgumentArgument ValueBuffer\n");
printf("================================================="
"=========\n");
for (x_sub = 0; x_sub < size; x_sub++)
{
len = testvals[x_sub].length;
digits = testvals[x_sub].digits;
value = testvals[x_sub].value;
rc = double_to_bcd(value, wrkbf, len, digits);
if (rc > 0)
{
printf( format, value, len, digits, rc );
for ( y_sub = 0; y_sub < rc; y_sub++ )
printf("%02X ", wrkbf[y_sub]);
printf("\n");
}
}
return 0;
}
#endif