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