Solved

bcd conversion

Posted on 1997-07-24
3
636 Views
Last Modified: 2012-08-13
what is the algorithm to convert a bcd numeric (cobol)
to a character string.
0
Comment
Question by:rjb072497
3 Comments
 
LVL 2

Expert Comment

by:Philippe
ID: 1252595

try this:

 sprintf(my_string,"%d",
         (my_bcd&0xff000000)*1000 +
         (my_bcd&0x00ff0000)*100  +
         (my_bcd&0x0000ff00)*10   +
         (my_bcd&0x000000ff));

 
for a 16 bit bcd number. If it doesn't work tell us more about where you get you bcd numeric from and how you store it in your program.

  Philippe

If it works, let me resubmit it as answer.

0
 
LVL 1

Accepted Solution

by:
8051 earned 100 total points
ID: 1252596
//Comment to this code from 8051:
//Use the best. Best is Borland!
/*------------------------------------------------------*
*filename - bcd1.c
*Library for long double / binary code decimal conversions
*-------------------------------------------------------*/

/*
 *      C/C++ Run Time Library - Version 5.0
 *
 *      Copyright (c) 1987, 1992 by Borland International
 *      All Rights Reserved.
 *
 */


#include <_defs.h>

/*
about 17 digits precision
exponent range, about 1e-125 to 1e+125

bcd format:
expo            mantissa                value
0               0                       0
1               +1 or -1                +INF or -INF
2               ?                       NAN
3-255           x                       x * 10 ^ (expo - Bias)

The Bias is 147, so exponent range is 3-147=-144 to 255-147=+108.
Caution: The decimal representation is not unique.
Eg, { 1L, 0L, 1+Bias } is the same as { 10L, 0L, 0+Bias }.
*/

#pragma  inline

typedef unsigned short bits16;

typedef struct
{
    bits16      frac [4];
    bits16      signExp;
}
    IEEE80;

struct decimal {
        long mantissa[2];
        short expo;
};

typedef struct decimal bcd;

enum bcdexpo {
        ExpoZero,
        ExpoInf,
        ExpoNan,
};

#define Bias    147

#define I asm

#define REAL    qword ptr
#define REAL1   dword ptr
#define REAL2   qword ptr
#define REAL3   tbyte ptr

#define BYTE    byte ptr
#define WORD    word ptr
#define LONG    dword ptr
#define LONG64  qword ptr

static const long e0toF [8] =
{
    1, 10, 100, 1000, 10000, 100000L, 1000000L, 10000000L
};

static const IEEE80 expo [10] =
{
    {{0,      0,      0x2000, 0xBEBC}, 0x4019},    /* 1e8    */
    {{0,      0x0400, 0xC9BF, 0x8E1B}, 0x4034},    /* 1e16   */
    {{0xB59E, 0x2B70, 0xADA8, 0x9DC5}, 0x4069},    /* 1e32   */
    {{0xA6D5, 0xFFCF, 0x1F49, 0xC278}, 0x40D3},    /* 1e64   */
    {{0x8CE0, 0x80E9, 0x47C9, 0x93BA}, 0x41A8},    /* 1e128  */
    {{0xDE8E, 0x9DF9, 0xEBFB, 0xAA7E}, 0x4351},    /* 1e256  */
    {{0x91C7, 0xA60E, 0xA0AE, 0xE319}, 0x46A3},    /* 1e512  */
    {{0x0C17, 0x8175, 0x7586, 0xC976}, 0x4D48},    /* 1e1024 */
    {{0x5DE5, 0xC53D, 0x3B5D, 0x9E8B}, 0x5A92},    /* 1e2048 */
    {{0x979B, 0x8A20, 0x5202, 0xC460}, 0x7525},    /* 1e4096 */
};

static void near pascal scale10(int p)
/* return
        TOS *= 10 ^ p
        preserves ax! (except in HUGE)
*/
{
I       mov     si, p
I       or      si, si
I       mov     dx, si
I       jz      scale_num
I       jns     scale_abs
I       neg     si
scale_abs:
I       cmp     si, 4999
I       jbe     scale_max
I       mov     si, 4999
scale_max:
/* load e0toF[_SI & 7] */
I       mov     bx, 7
I       and     bx, si
I       shl     bx, 1
I       shl     bx, 1
I       add     bx, offset e0toF
I       fild    LONG [bx]

I       mov     cl, 3
I       shr     si, cl
I       mov     di, offset expo
expo_loop:
I       or      si, si
I       jz      scale_num
I       shr     si, 1
I       jnc     expo_next
I       fld     REAL3 [di]
I       fmul

expo_next:
I       add     di, 10
I       jmp     expo_loop

scale_num:
I       or      dx, dx
I       jz      scale_end
I       jns     scale_mul
I       fdiv
I       jmp     short scale_end
scale_mul:
I       fmul

scale_end:
        return;
}

static const float inf = 1.0/0.0;
static const float nan = 0.0/0.0;

/*
Convert a decimal number to binary.
*/

long double pascal _FARFUNC __bcd_tobinary(const bcd far *p)
{
I       les     bx, p
I       fild    LONG64 es:[bx]          /* p->mantissa */
I       mov     ax, es:[bx+8]           /* p->expo */

I       cmp     al, 2
I       jbe     special
I       sub     ax, Bias
#ifdef __HUGE__
I   push ax
#endif
        scale10(_AX);           /* Preserves AX except in huge model */
#ifdef __HUGE__
I   pop ax
#endif
I       jmp     short done

special:
I       je      nan
I       or      al, al
I       jz      zero

I       fmul    REAL1 inf               /* mantissa was +1 or -1 */
I       jmp     short done

nan:
I       fstp    st(0)
I       fld     REAL1 nan
        /* fall thru */

zero:
/* assume mantissa is 0 */
done:
#pragma warn -rvl       /* Function should return a value */
        return;
#pragma warn .rvl       /* Function should return a value */
}

/*
round x to n decimal places
fixed point!
eg,
x = 123.4567;
round(x, 0) = 123.
round(x, 1) = 123.5
round(x, 2) = 123.46
round(x, -1) = 120.
round(x, -2) = 100.

uses banker's rounding

Convert a binary number to decimals.
Use at most 'decimals' after the decimal point.
For maximum accuracy, use decimals=5000.
*/

void pascal _FARFUNC __bcd_todecimal(long double x, int decimals, bcd far *p)
{
I       mov     ax, x[8]
I       mov     dx, x[6]
I       mov     cx, 7FFFh
I       les     si, p

I       and     ax, cx
I       jz      zero
I       cmp     ax, cx
I       je      special

I       sub     ax, 3FFFh + 60
I       neg     ax

#if 0
I       shl     dx, 1
I       shl     dx, 1
I       rcl     ax, 1
I       shl     dx, 1
I       rcl     ax, 1

I       mov     dx, 92A0h shr 1
I       imul    dx

I       xchg    ax, dx
I       sar     ax, 1
I       sar     ax, 1

#else
I       mov     dx, 9A20h shr 1 /* log10(2) */
I       imul    dx
I       xchg    ax, dx
#endif

/* use min(ax,n) */
I       mov     dx, decimals
I       cmp     ax, dx
I       jl      min
I       xchg    ax, dx
min:

/* -ax is unbiased exponent, not special, so -144 <= -ax <= 108 */
I       cmp     ax, +144
I       jg      underflow
I       cmp     ax, -108
I       jl      overflow

I       fld     REAL3 x
#ifdef __HUGE__
I   push ax
#endif
        scale10(_AX);           /* Preserves AX except in huge model */
#ifdef __HUGE__
I   pop ax
#endif

I       neg     ax
I       add     ax, Bias
I       jmp     short done

special:
I       or      dx, dx
I       jz      nan

overflow:
I       fld1
I       mov     al, ExpoInf
I       test    BYTE x[9], 80h
I       jz      done
I       fchs
I       jmp     short done

nan:
I       fldz
I       mov     al, ExpoNan
I       jmp     short done

underflow:
zero:
I       fldz
I       mov     al, ExpoZero

done:
I       fistp   LONG64 es:[si]
I       mov     ah, 0
I       mov     es:[si+8], ax
I       fwait
}

#if     DEBUG
/* for debugging */
long double pascal load64(long far *a)
{
I       les     bx, a
I       fild    LONG64 es:[bx]
        return;
}
#endif

/* from _mathl.h */
typedef enum {
        _Sine_,_CoSine_,_Tangent_,_ArcTan_,
        _Log_,_Log2_, _Log10_,
        _Exp_,_Exp2_, _Exp10_,_Power_
} FLIB_functions;

#define FLIB_(fun)      _FAST_(0ECh + 2*fun)
#define _FAST_(shortCode)       int     3Eh;  asm db    shortCode, 90h

#pragma warn -rvl
long double pascal _FARFUNC __bcd_log10(bcd far *p)
{
I       les     bx, p
I       fild    LONG64 es:[bx]
asm     FLIB_   (_Log10_)
I       sub     WORD es:[bx+8], Bias
I       fiadd   WORD es:[bx+8]
I       add     WORD es:[bx+8], Bias
I       fwait
        return;
}
#pragma warn .rvl

void pascal _FARFUNC __bcd_pow10(int n, bcd far *p)
{
        p->mantissa[0] = 1;
        p->mantissa[1] = 0;
        _AX = n;
I       add     ax, Bias
I       cmp     ax, 255
I       jg      inf
I       cmp     ax, 3
I       jl      zero
        p->expo = _AX;
        return;

zero:
        p->mantissa[0] = 0;
        p->expo = 0;
        return;

inf:
        p->expo = ExpoInf;
        return;
}



0
 
LVL 84

Expert Comment

by:ozo
ID: 1252597
     /*or maybe even*/
      sprintf(my_string,"%x",my_bcd);

0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now