home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / DTOTP6.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  3KB  |  119 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4. $Header: c:/bnxl/rcs/dtotp6.c 1.2 1995/05/01 00:30:58 bnelson Exp $
  5.  
  6. $Log: dtotp6.c $
  7. Revision 1.2  1995/05/01 00:30:58  bnelson
  8.  
  9. - Added test driver and Thad Smith's original function
  10.   to convert a TP real to double
  11.  
  12. - Checks out OK with lint.
  13.  
  14. - Tested on GNU C 2.6.3 (little endian Intel) after adding PAK to
  15.   real struct.
  16.  
  17. Revision 1.1  1995/04/30 23:54:56  bnelson
  18.  
  19. Written by Bob Nelson of Dallas, TX, USA (bnelson@netcom.com)
  20.  
  21. Original tp6_to_double() written by Thad Smith III of Boulder, CO, and
  22.   released to the public domain in SNIPPETS
  23.  
  24. - Initial release -- converts C double value into the bit pattern used
  25.   by a Turbo Pascal 6-byte real. Uses the "real" struct written by Thad
  26.   Smith for ease of assignment to members.
  27.  
  28. - Tested on BC++ 3.1. 
  29.  
  30. - This source and associated include are contributed to the Public Domain.
  31. */
  32.  
  33.  
  34. #include <math.h>
  35. #include "dtotp6.h"
  36.  
  37.  
  38. #define DBL_BIAS            0x3FE
  39. #define REAL_BIAS           0x80
  40. #define TP_REAL_BIAS        (DBL_BIAS - REAL_BIAS)    /* 0x37E */
  41.  
  42.  
  43. tp_real_t double_to_tp6(double x)
  44. {
  45.       unsigned int *wp;
  46.       tp_real_t r;
  47.  
  48.       if(x == 0.0)
  49.       {
  50.             r.v3 = r.v2 = r.v1 = r.be = r.s = 0;
  51.             return r;
  52.       }
  53.  
  54.       wp = (void *)&x;            /* Break down double into words */
  55.  
  56.       r.s  = wp[3] >> 15;         /* High bit set for sign */
  57.  
  58.       /* -------------------------------------------------------------------
  59.       ** Grab biased exponent -- exclude sign and shift out the MSB
  60.       ** mantissa bits.
  61.       */
  62.  
  63.       r.be = (unsigned char)(((wp[3] & 0x7FFF) >> 4) - TP_REAL_BIAS);
  64.  
  65.       /* ------------------------------------------------------------------
  66.       ** Now...just assign the mantissa after shifting the bits to conform
  67.       ** with the layout for the TP 6-byte real.
  68.       */
  69.  
  70.       r.v3 = ((wp[3] & 0x0F) << 3) | (wp[2] >> 13);
  71.       r.v2 = (wp[2] << 3) | (wp[1] >> 13);
  72.       r.v1 = (wp[1] << 3) | (wp[0] >> 13);
  73.  
  74.       return r;
  75. }
  76.  
  77.  
  78. /* -----------------------------------------------------------------
  79. ** Slightly adapted version of Thad Smith's function from TP6TOD.C
  80. ** from Snippets. (Uses TP real struct parameter and no memcpy).
  81. */
  82.  
  83.  
  84. double tp6_to_double(tp_real_t r)
  85. {
  86.       if (r.be == 0)
  87.             return 0.0;
  88.  
  89.       return ((((128 + r.v3) * 65536.0) + r.v2) * 65536.0 + r.v1) *
  90.             ldexp((r.s ? -1.0 : 1.0), r.be - (129 + 39));
  91. }
  92.  
  93. #if defined (TEST)
  94.  
  95. #include <stdio.h>
  96. #include <stdlib.h>
  97.  
  98.  
  99.  
  100. int main(int argc, char **argv)
  101. {
  102.       double x, y;
  103.       tp_real_t r;
  104.  
  105.       if(argc > 1)
  106.             x = strtod(argv[1], NULL);
  107.       else  x = 19999.99;
  108.  
  109.       r = double_to_tp6(x);
  110.       y = tp6_to_double(r);
  111.  
  112.       printf("input double value: %.2f, converted double value: %.2f\n",
  113.             x, y);
  114.  
  115.       return 0;
  116. }
  117.  
  118. #endif    /* TEST */
  119.