Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2177 lines
53 KiB

  1. /***
  2. *float10.c - floating point output for 10-byte long double
  3. *
  4. * Copyright (c) 1991-1991, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Support conversion of a long double into a string
  8. *
  9. *Revision History:
  10. * 07/15/91 GDP Initial version in C (ported from assembly)
  11. * 01/23/92 GDP Support MIPS encoding for NaN
  12. * 05-26-92 GWK Windbg srcs
  13. *
  14. ******************************************************************************/
  15. #include "pch.hpp"
  16. #include <math.h>
  17. #include "float10.h"
  18. typedef LONG s_long;
  19. typedef ULONG u_long;
  20. typedef SHORT s_short;
  21. typedef USHORT u_short;
  22. #define L_END
  23. #define PTR_LD(x) ((u_char *)(&(x)->ld))
  24. #define PTR_12(x) ((u_char *)(&(x)->ld12))
  25. #define MAX_USHORT ((u_short)0xffff)
  26. #define MSB_USHORT ((u_short)0x8000)
  27. #define MAX_ULONG ((u_long)0xffffffff)
  28. #define MSB_ULONG ((u_long)0x80000000)
  29. #define TMAX10 5200 /* maximum temporary decimal exponent */
  30. #define TMIN10 -5200 /* minimum temporary decimal exponent */
  31. #define LD_MAX_EXP_LEN 4 /* maximum number of decimal exponent digits */
  32. #define LD_MAX_MAN_LEN 24 /* maximum length of mantissa (decimal)*/
  33. #define LD_MAX_MAN_LEN1 25 /* MAX_MAN_LEN+1 */
  34. #define LD_BIAS 0x3fff /* exponent bias for long double */
  35. #define LD_BIASM1 0x3ffe /* LD_BIAS - 1 */
  36. #define LD_MAXEXP 0x7fff /* maximum biased exponent */
  37. #define D_BIAS 0x3ff /* exponent bias for double */
  38. #define D_BIASM1 0x3fe /* D_BIAS - 1 */
  39. #define D_MAXEXP 0x7ff /* maximum biased exponent */
  40. /* Recognizing special patterns in the mantissa field */
  41. #define _EXP_SP 0x7fff
  42. #define NAN_BIT (1<<30)
  43. #define _IS_MAN_INF(signbit, manhi, manlo) \
  44. ( (manhi)==MSB_ULONG && (manlo)==0x0 )
  45. #define _IS_MAN_IND(signbit, manhi, manlo) \
  46. ((signbit) && (manhi)==0xc0000000 && (manlo)==0)
  47. #define _IS_MAN_QNAN(signbit, manhi, manlo) \
  48. ( (manhi)&NAN_BIT )
  49. #define _IS_MAN_SNAN(signbit, manhi, manlo) \
  50. (!( _IS_MAN_INF(signbit, manhi, manlo) || \
  51. _IS_MAN_QNAN(signbit, manhi, manlo) ))
  52. /*
  53. * Manipulation of a 12-byte long double number (an ordinary
  54. * 10-byte long double plus two extra bytes of mantissa).
  55. */
  56. /* a pointer to the exponent/sign portion */
  57. #define U_EXP_12(p) ((u_short *)(PTR_12(p)+10))
  58. /* a pointer to the 4 hi-order bytes of the mantissa */
  59. #define UL_MANHI_12(p) ((u_long UNALIGNED *)(PTR_12(p)+6))
  60. /* a pointer to the 4 lo-order bytes of the ordinary (8-byte) mantissa */
  61. #define UL_MANLO_12(p) ((u_long UNALIGNED *)(PTR_12(p)+2))
  62. /* a pointer to the 2 extra bytes of the mantissa */
  63. #define U_XT_12(p) ((u_short *)PTR_12(p))
  64. /* a pointer to the 4 lo-order bytes of the extended (10-byte) mantissa */
  65. #define UL_LO_12(p) ((u_long UNALIGNED *)PTR_12(p))
  66. /* a pointer to the 4 mid-order bytes of the extended (10-byte) mantissa */
  67. #define UL_MED_12(p) ((u_long UNALIGNED *)(PTR_12(p)+4))
  68. /* a pointer to the 4 hi-order bytes of the extended long double */
  69. #define UL_HI_12(p) ((u_long UNALIGNED *)(PTR_12(p)+8))
  70. /* a pointer to the byte of order i (LSB=0, MSB=9)*/
  71. #define UCHAR_12(p,i) ((u_char *)PTR_12(p)+(i))
  72. /* a pointer to a u_short with offset i */
  73. #define USHORT_12(p,i) ((u_short *)((u_char *)PTR_12(p)+(i)))
  74. /* a pointer to a u_long with offset i */
  75. #define ULONG_12(p,i) ((u_long UNALIGNED *)((u_char *)PTR_12(p)+(i)))
  76. /* a pointer to the 10 MSBytes of a 12-byte long double */
  77. #define TEN_BYTE_PART(p) ((u_char *)PTR_12(p)+2)
  78. /*
  79. * Manipulation of a 10-byte long double number
  80. */
  81. #define U_EXP_LD(p) ((u_short *)(PTR_LD(p)+8))
  82. #define UL_MANHI_LD(p) ((u_long UNALIGNED *)(PTR_LD(p)+4))
  83. #define UL_MANLO_LD(p) ((u_long UNALIGNED *)PTR_LD(p))
  84. /*
  85. * Manipulation of a 64bit IEEE double
  86. */
  87. #define U_SHORT4_D(p) ((u_short *)(p) + 3)
  88. #define UL_HI_D(p) ((u_long UNALIGNED *)(p) + 1)
  89. #define UL_LO_D(p) ((u_long UNALIGNED *)(p))
  90. #define PUT_INF_12(p,sign) \
  91. *UL_HI_12(p) = (sign)?0xffff8000:0x7fff8000; \
  92. *UL_MED_12(p) = 0; \
  93. *UL_LO_12(p) = 0;
  94. #define PUT_ZERO_12(p) *UL_HI_12(p) = 0; \
  95. *UL_MED_12(p) = 0; \
  96. *UL_LO_12(p) = 0;
  97. #define ISZERO_12(p) ((*UL_HI_12(p)&0x7fffffff) == 0 && \
  98. *UL_MED_12(p) == 0 && \
  99. *UL_LO_12(p) == 0 )
  100. #define PUT_INF_LD(p,sign) \
  101. *U_EXP_LD(p) = (sign)?0xffff:0x7fff; \
  102. *UL_MANHI_LD(p) = 0x8000; \
  103. *UL_MANLO_LD(p) = 0;
  104. #define PUT_ZERO_LD(p) *U_EXP_LD(p) = 0; \
  105. *UL_MANHI_LD(p) = 0; \
  106. *UL_MANLO_LD(p) = 0;
  107. #define ISZERO_LD(p) ((*U_EXP_LD(p)&0x7fff) == 0 && \
  108. *UL_MANHI_LD(p) == 0 && \
  109. *UL_MANLO_LD(p) == 0 )
  110. /* Format: A 10 byte long double + 2 bytes of extra precision
  111. * If the extra precision is desired, the 10-byte long double
  112. * should be "unrounded" first.
  113. * This may change in later versions
  114. */
  115. #ifdef L_END
  116. _ULDBL12 _pow10pos[] = {
  117. /*P0001*/ {{0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0x02,0x40}},
  118. /*P0002*/ {{0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC8,0x05,0x40}},
  119. /*P0003*/ {{0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFA,0x08,0x40}},
  120. /*P0004*/ {{0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x9C,0x0C,0x40}},
  121. /*P0005*/ {{0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x50,0xC3,0x0F,0x40}},
  122. /*P0006*/ {{0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x24,0xF4,0x12,0x40}},
  123. /*P0007*/ {{0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x80,0x96,0x98,0x16,0x40}},
  124. /*P0008*/ {{0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x20,0xBC,0xBE,0x19,0x40}},
  125. /*P0016*/ {{0x00,0x00, 0x00,0x00,0x00,0x04,0xBF,0xC9,0x1B,0x8E,0x34,0x40}},
  126. /*P0024*/ {{0x00,0x00, 0x00,0xA1,0xED,0xCC,0xCE,0x1B,0xC2,0xD3,0x4E,0x40}},
  127. /*P0032*/ {{0x20,0xF0, 0x9E,0xB5,0x70,0x2B,0xA8,0xAD,0xC5,0x9D,0x69,0x40}},
  128. /*P0040*/ {{0xD0,0x5D, 0xFD,0x25,0xE5,0x1A,0x8E,0x4F,0x19,0xEB,0x83,0x40}},
  129. /*P0048*/ {{0x71,0x96, 0xD7,0x95,0x43,0x0E,0x05,0x8D,0x29,0xAF,0x9E,0x40}},
  130. /*P0056*/ {{0xF9,0xBF, 0xA0,0x44,0xED,0x81,0x12,0x8F,0x81,0x82,0xB9,0x40}},
  131. /*P0064*/ {{0xBF,0x3C, 0xD5,0xA6,0xCF,0xFF,0x49,0x1F,0x78,0xC2,0xD3,0x40}},
  132. /*P0128*/ {{0x6F,0xC6, 0xE0,0x8C,0xE9,0x80,0xC9,0x47,0xBA,0x93,0xA8,0x41}},
  133. /*P0192*/ {{0xBC,0x85, 0x6B,0x55,0x27,0x39,0x8D,0xF7,0x70,0xE0,0x7C,0x42}},
  134. /*P0256*/ {{0xBC,0xDD, 0x8E,0xDE,0xF9,0x9D,0xFB,0xEB,0x7E,0xAA,0x51,0x43}},
  135. /*P0320*/ {{0xA1,0xE6, 0x76,0xE3,0xCC,0xF2,0x29,0x2F,0x84,0x81,0x26,0x44}},
  136. /*P0384*/ {{0x28,0x10, 0x17,0xAA,0xF8,0xAE,0x10,0xE3,0xC5,0xC4,0xFA,0x44}},
  137. /*P0448*/ {{0xEB,0xA7, 0xD4,0xF3,0xF7,0xEB,0xE1,0x4A,0x7A,0x95,0xCF,0x45}},
  138. /*P0512*/ {{0x65,0xCC, 0xC7,0x91,0x0E,0xA6,0xAE,0xA0,0x19,0xE3,0xA3,0x46}},
  139. /*P1024*/ {{0x0D,0x65, 0x17,0x0C,0x75,0x81,0x86,0x75,0x76,0xC9,0x48,0x4D}},
  140. /*P1536*/ {{0x58,0x42, 0xE4,0xA7,0x93,0x39,0x3B,0x35,0xB8,0xB2,0xED,0x53}},
  141. /*P2048*/ {{0x4D,0xA7, 0xE5,0x5D,0x3D,0xC5,0x5D,0x3B,0x8B,0x9E,0x92,0x5A}},
  142. /*P2560*/ {{0xFF,0x5D, 0xA6,0xF0,0xA1,0x20,0xC0,0x54,0xA5,0x8C,0x37,0x61}},
  143. /*P3072*/ {{0xD1,0xFD, 0x8B,0x5A,0x8B,0xD8,0x25,0x5D,0x89,0xF9,0xDB,0x67}},
  144. /*P3584*/ {{0xAA,0x95, 0xF8,0xF3,0x27,0xBF,0xA2,0xC8,0x5D,0xDD,0x80,0x6E}},
  145. /*P4096*/ {{0x4C,0xC9, 0x9B,0x97,0x20,0x8A,0x02,0x52,0x60,0xC4,0x25,0x75}}
  146. };
  147. _ULDBL12 _pow10neg[] = {
  148. /*N0001*/ {{0xCD,0xCC, 0xCD,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xFB,0x3F}},
  149. /*N0002*/ {{0x71,0x3D, 0x0A,0xD7,0xA3,0x70,0x3D,0x0A,0xD7,0xA3,0xF8,0x3F}},
  150. /*N0003*/ {{0x5A,0x64, 0x3B,0xDF,0x4F,0x8D,0x97,0x6E,0x12,0x83,0xF5,0x3F}},
  151. /*N0004*/ {{0xC3,0xD3, 0x2C,0x65,0x19,0xE2,0x58,0x17,0xB7,0xD1,0xF1,0x3F}},
  152. /*N0005*/ {{0xD0,0x0F, 0x23,0x84,0x47,0x1B,0x47,0xAC,0xC5,0xA7,0xEE,0x3F}},
  153. /*N0006*/ {{0x40,0xA6, 0xB6,0x69,0x6C,0xAF,0x05,0xBD,0x37,0x86,0xEB,0x3F}},
  154. /*N0007*/ {{0x33,0x3D, 0xBC,0x42,0x7A,0xE5,0xD5,0x94,0xBF,0xD6,0xE7,0x3F}},
  155. /*N0008*/ {{0xC2,0xFD, 0xFD,0xCE,0x61,0x84,0x11,0x77,0xCC,0xAB,0xE4,0x3F}},
  156. /*N0016*/ {{0x2F,0x4C, 0x5B,0xE1,0x4D,0xC4,0xBE,0x94,0x95,0xE6,0xC9,0x3F}},
  157. /*N0024*/ {{0x92,0xC4, 0x53,0x3B,0x75,0x44,0xCD,0x14,0xBE,0x9A,0xAF,0x3F}},
  158. /*N0032*/ {{0xDE,0x67, 0xBA,0x94,0x39,0x45,0xAD,0x1E,0xB1,0xCF,0x94,0x3F}},
  159. /*N0040*/ {{0x24,0x23, 0xC6,0xE2,0xBC,0xBA,0x3B,0x31,0x61,0x8B,0x7A,0x3F}},
  160. /*N0048*/ {{0x61,0x55, 0x59,0xC1,0x7E,0xB1,0x53,0x7C,0x12,0xBB,0x5F,0x3F}},
  161. /*N0056*/ {{0xD7,0xEE, 0x2F,0x8D,0x06,0xBE,0x92,0x85,0x15,0xFB,0x44,0x3F}},
  162. /*N0064*/ {{0x24,0x3F, 0xA5,0xE9,0x39,0xA5,0x27,0xEA,0x7F,0xA8,0x2A,0x3F}},
  163. /*N0128*/ {{0x7D,0xAC, 0xA1,0xE4,0xBC,0x64,0x7C,0x46,0xD0,0xDD,0x55,0x3E}},
  164. /*N0192*/ {{0x63,0x7B, 0x06,0xCC,0x23,0x54,0x77,0x83,0xFF,0x91,0x81,0x3D}},
  165. /*N0256*/ {{0x91,0xFA, 0x3A,0x19,0x7A,0x63,0x25,0x43,0x31,0xC0,0xAC,0x3C}},
  166. /*N0320*/ {{0x21,0x89, 0xD1,0x38,0x82,0x47,0x97,0xB8,0x00,0xFD,0xD7,0x3B}},
  167. /*N0384*/ {{0xDC,0x88, 0x58,0x08,0x1B,0xB1,0xE8,0xE3,0x86,0xA6,0x03,0x3B}},
  168. /*N0448*/ {{0xC6,0x84, 0x45,0x42,0x07,0xB6,0x99,0x75,0x37,0xDB,0x2E,0x3A}},
  169. /*N0512*/ {{0x33,0x71, 0x1C,0xD2,0x23,0xDB,0x32,0xEE,0x49,0x90,0x5A,0x39}},
  170. /*N1024*/ {{0xA6,0x87, 0xBE,0xC0,0x57,0xDA,0xA5,0x82,0xA6,0xA2,0xB5,0x32}},
  171. /*N1536*/ {{0xE2,0x68, 0xB2,0x11,0xA7,0x52,0x9F,0x44,0x59,0xB7,0x10,0x2C}},
  172. /*N2048*/ {{0x25,0x49, 0xE4,0x2D,0x36,0x34,0x4F,0x53,0xAE,0xCE,0x6B,0x25}},
  173. /*N2560*/ {{0x8F,0x59, 0x04,0xA4,0xC0,0xDE,0xC2,0x7D,0xFB,0xE8,0xC6,0x1E}},
  174. /*N3072*/ {{0x9E,0xE7, 0x88,0x5A,0x57,0x91,0x3C,0xBF,0x50,0x83,0x22,0x18}},
  175. /*N3584*/ {{0x4E,0x4B, 0x65,0x62,0xFD,0x83,0x8F,0xAF,0x06,0x94,0x7D,0x11}},
  176. /*N4096*/ {{0xE4,0x2D, 0xDE,0x9F,0xCE,0xD2,0xC8,0x04,0xDD,0xA6,0xD8,0x0A}}
  177. };
  178. #endif
  179. int __addl(u_long x, u_long y, u_long UNALIGNED *sum)
  180. {
  181. u_long r;
  182. int carry=0;
  183. r = x+y;
  184. if (r < x || r < y)
  185. carry++;
  186. *sum = r;
  187. return carry;
  188. }
  189. /***
  190. *void __add_12(_ULDBL12 *x, _ULDBL12 *y) - _ULDBL12 addition
  191. *
  192. *Purpose: add two _ULDBL12 numbers. The numbers are added
  193. * as 12-byte integers. Overflow is ignored.
  194. *
  195. *Entry: x,y: pointers to the operands
  196. *
  197. *Exit: *x receives the sum
  198. *
  199. *Exceptions:
  200. *
  201. *******************************************************************************/
  202. void __add_12(_ULDBL12 *x, _ULDBL12 *y)
  203. {
  204. int c0,c1,c2;
  205. c0 = __addl(*UL_LO_12(x),*UL_LO_12(y),UL_LO_12(x));
  206. if (c0) {
  207. c1 = __addl(*UL_MED_12(x),(u_long)1,UL_MED_12(x));
  208. if (c1) {
  209. (*UL_HI_12(x))++;
  210. }
  211. }
  212. c2 = __addl(*UL_MED_12(x),*UL_MED_12(y),UL_MED_12(x));
  213. if (c2) {
  214. (*UL_HI_12(x))++;
  215. }
  216. /* ignore next carry -- assume no overflow will occur */
  217. (void) __addl(*UL_HI_12(x),*UL_HI_12(y),UL_HI_12(x));
  218. }
  219. /***
  220. *void __shl_12(_ULDBL12 *x) - _ULDBL12 shift left
  221. *void __shr_12(_ULDBL12 *x) - _ULDBL12 shift right
  222. *
  223. *Purpose: Shift a _ULDBL12 number one bit to the left (right). The number
  224. * is shifted as a 12-byte integer. The MSB is lost.
  225. *
  226. *Entry: x: a pointer to the operand
  227. *
  228. *Exit: *x is shifted one bit to the left (or right)
  229. *
  230. *Exceptions:
  231. *
  232. *******************************************************************************/
  233. void __shl_12(_ULDBL12 *p)
  234. {
  235. u_long c0,c1;
  236. c0 = *UL_LO_12(p) & MSB_ULONG ? 1: 0;
  237. c1 = *UL_MED_12(p) & MSB_ULONG ? 1: 0;
  238. *UL_LO_12(p) <<= 1;
  239. *UL_MED_12(p) = *UL_MED_12(p)<<1 | c0;
  240. *UL_HI_12(p) = *UL_HI_12(p)<<1 | c1;
  241. }
  242. void __shr_12(_ULDBL12 *p)
  243. {
  244. u_long c2,c1;
  245. c2 = *UL_HI_12(p) & 0x1 ? MSB_ULONG: 0;
  246. c1 = *UL_MED_12(p) & 0x1 ? MSB_ULONG: 0;
  247. *UL_HI_12(p) >>= 1;
  248. *UL_MED_12(p) = *UL_MED_12(p)>>1 | c2;
  249. *UL_LO_12(p) = *UL_LO_12(p)>>1 | c1;
  250. }
  251. /***
  252. *void __ld12mul(_ULDBL12 *px, _ULDBL12 *py) -
  253. * _ULDBL12 multiplication
  254. *
  255. *Purpose: multiply two _ULDBL12 numbers
  256. *
  257. *Entry: px,py: pointers to the _ULDBL12 operands
  258. *
  259. *Exit: *px contains the product
  260. *
  261. *Exceptions:
  262. *
  263. *******************************************************************************/
  264. void __ld12mul(_ULDBL12 *px, _ULDBL12 *py)
  265. {
  266. u_short sign = 0;
  267. u_short sticky_bits = 0;
  268. _ULDBL12 tempman; /*this is actually a 12-byte mantissa,
  269. not a 12-byte long double */
  270. int i;
  271. u_short expx, expy, expsum;
  272. int roffs,poffs,qoffs;
  273. int sticky;
  274. *UL_LO_12(&tempman) = 0;
  275. *UL_MED_12(&tempman) = 0;
  276. *UL_HI_12(&tempman) = 0;
  277. expx = *U_EXP_12(px);
  278. expy = *U_EXP_12(py);
  279. sign = (expx ^ expy) & (u_short)0x8000;
  280. expx &= 0x7fff;
  281. expy &= 0x7fff;
  282. expsum = expx+expy;
  283. if (expx >= LD_MAXEXP
  284. || expy >= LD_MAXEXP
  285. || expsum > LD_MAXEXP+ LD_BIASM1){
  286. /* overflow to infinity */
  287. PUT_INF_12(px,sign);
  288. return;
  289. }
  290. if (expsum <= LD_BIASM1-63) {
  291. /* underflow to zero */
  292. PUT_ZERO_12(px);
  293. return;
  294. }
  295. if (expx == 0) {
  296. /*
  297. * If this is a denormal temp real then the mantissa
  298. * was shifted right once to set bit 63 to zero.
  299. */
  300. expsum++; /* Correct for this */
  301. if (ISZERO_12(px)) {
  302. /* put positive sign */
  303. *U_EXP_12(px) = 0;
  304. return;
  305. }
  306. }
  307. if (expy == 0) {
  308. expsum++; /* because arg2 is denormal */
  309. if (ISZERO_12(py)) {
  310. PUT_ZERO_12(px);
  311. return;
  312. }
  313. }
  314. roffs = 0;
  315. for (i=0;i<5;i++) {
  316. int j;
  317. poffs = i<<1;
  318. qoffs = 8;
  319. for (j=5-i;j>0;j--) {
  320. u_long prod;
  321. #ifdef MIPS
  322. /* a variable to hold temprary sums */
  323. u_long sum;
  324. #endif
  325. int carry;
  326. u_short *p, *q;
  327. u_long UNALIGNED *r;
  328. p = USHORT_12(px,poffs);
  329. q = USHORT_12(py,qoffs);
  330. r = ULONG_12(&tempman,roffs);
  331. prod = (u_long)*p * (u_long)*q;
  332. #ifdef MIPS
  333. /* handle misalignment problems */
  334. if (i&0x1){ /* i is odd */
  335. carry = __addl(*MIPSALIGN(r), prod, &sum);
  336. *MIPSALIGN(r) = sum;
  337. }
  338. else /* i is even */
  339. carry = __addl(*r, prod, r);
  340. #else
  341. carry = __addl(*r,prod,r);
  342. #endif
  343. if (carry) {
  344. /* roffs should be less than 8 in this case */
  345. (*USHORT_12(&tempman,roffs+4))++;
  346. }
  347. poffs+=2;
  348. qoffs-=2;
  349. }
  350. roffs+=2;
  351. }
  352. expsum -= LD_BIASM1;
  353. /* normalize */
  354. while ((s_short)expsum > 0 &&
  355. ((*UL_HI_12(&tempman) & MSB_ULONG) == 0)) {
  356. __shl_12(&tempman);
  357. expsum--;
  358. }
  359. if ((s_short)expsum <= 0) {
  360. expsum--;
  361. sticky = 0;
  362. while ((s_short)expsum < 0) {
  363. if (*U_XT_12(&tempman) & 0x1)
  364. sticky++;
  365. __shr_12(&tempman);
  366. expsum++;
  367. }
  368. if (sticky)
  369. *U_XT_12(&tempman) |= 0x1;
  370. }
  371. if (*U_XT_12(&tempman) > 0x8000 ||
  372. ((*UL_LO_12(&tempman) & 0x1ffff) == 0x18000)) {
  373. /* round up */
  374. if (*UL_MANLO_12(&tempman) == MAX_ULONG) {
  375. *UL_MANLO_12(&tempman) = 0;
  376. if (*UL_MANHI_12(&tempman) == MAX_ULONG) {
  377. *UL_MANHI_12(&tempman) = 0;
  378. if (*U_EXP_12(&tempman) == MAX_USHORT) {
  379. /* 12-byte mantissa overflow */
  380. *U_EXP_12(&tempman) = MSB_USHORT;
  381. expsum++;
  382. }
  383. else
  384. (*U_EXP_12(&tempman))++;
  385. }
  386. else
  387. (*UL_MANHI_12(&tempman))++;
  388. }
  389. else
  390. (*UL_MANLO_12(&tempman))++;
  391. }
  392. /* check for exponent overflow */
  393. if (expsum >= 0x7fff){
  394. PUT_INF_12(px, sign);
  395. return;
  396. }
  397. /* put result in px */
  398. *U_XT_12(px) = *USHORT_12(&tempman,2);
  399. *UL_MANLO_12(px) = *UL_MED_12(&tempman);
  400. *UL_MANHI_12(px) = *UL_HI_12(&tempman);
  401. *U_EXP_12(px) = expsum | sign;
  402. }
  403. void __multtenpow12(_ULDBL12 *pld12, int pow, unsigned mult12)
  404. {
  405. _ULDBL12 *pow_10p = _pow10pos-8;
  406. if (pow == 0)
  407. return;
  408. if (pow < 0) {
  409. pow = -pow;
  410. pow_10p = _pow10neg-8;
  411. }
  412. if (!mult12)
  413. *U_XT_12(pld12) = 0;
  414. while (pow) {
  415. int last3; /* the 3 LSBits of pow */
  416. _ULDBL12 unround;
  417. _ULDBL12 *py;
  418. pow_10p += 7;
  419. last3 = pow & 0x7;
  420. pow >>= 3;
  421. if (last3 == 0)
  422. continue;
  423. py = pow_10p + last3;
  424. #ifdef _ULDSUPPORT
  425. if (mult12) {
  426. #endif
  427. /* do an exact 12byte multiplication */
  428. if (*U_XT_12(py) >= 0x8000) {
  429. /* copy number */
  430. unround = *py;
  431. /* unround adjacent byte */
  432. (*UL_MANLO_12(&unround))--;
  433. /* point to new operand */
  434. py = &unround;
  435. }
  436. __ld12mul(pld12,py);
  437. #ifdef _ULDSUPPORT
  438. }
  439. else {
  440. /* do a 10byte multiplication */
  441. py = (_ULDBL12 *)TEN_BYTE_PART(py);
  442. *(long double *)TEN_BYTE_PART(pld12) *=
  443. *(long double *)py;
  444. }
  445. #endif
  446. }
  447. }
  448. /***
  449. *void __mtold12(char *manptr,unsigned manlen,_ULDBL12 *ld12) -
  450. * convert a mantissa into a _ULDBL12
  451. *
  452. *Purpose: convert a mantissa into a _ULDBL12. The mantissa is
  453. * in the form of an array of manlen BCD digits and is
  454. * considered to be an integer.
  455. *
  456. *Entry: manptr: the array containing the packed BCD digits of the mantissa
  457. * manlen: the size of the array
  458. * ld12: a pointer to the long double where the result will be stored
  459. *
  460. *Exit:
  461. * ld12 gets the result of the conversion
  462. *
  463. *Exceptions:
  464. *
  465. *******************************************************************************/
  466. void __mtold12(char *manptr,
  467. unsigned manlen,
  468. _ULDBL12 *ld12)
  469. {
  470. _ULDBL12 tmp;
  471. u_short expn = LD_BIASM1+80;
  472. *UL_LO_12(ld12) = 0;
  473. *UL_MED_12(ld12) = 0;
  474. *UL_HI_12(ld12) = 0;
  475. for (;manlen>0;manlen--,manptr++){
  476. tmp = *ld12;
  477. __shl_12(ld12);
  478. __shl_12(ld12);
  479. __add_12(ld12,&tmp);
  480. __shl_12(ld12); /* multiply by 10 */
  481. *UL_LO_12(&tmp) = (u_long)*manptr;
  482. *UL_MED_12(&tmp) = 0;
  483. *UL_HI_12(&tmp) = 0;
  484. __add_12(ld12,&tmp);
  485. }
  486. /* normalize mantissa -- first shift word by word */
  487. while (*UL_HI_12(ld12) == 0) {
  488. *UL_HI_12(ld12) = *UL_MED_12(ld12) >> 16;
  489. *UL_MED_12(ld12) = *UL_MED_12(ld12) << 16 | *UL_LO_12(ld12) >> 16;
  490. (*UL_LO_12(ld12)) <<= 16;
  491. expn -= 16;
  492. }
  493. while ((*UL_HI_12(ld12) & 0x8000) == 0) {
  494. __shl_12(ld12);
  495. expn--;
  496. }
  497. *U_EXP_12(ld12) = expn;
  498. }
  499. #define STRCPY strcpy
  500. #define PUT_ZERO_FOS(fos) \
  501. fos->exp = 1, \
  502. fos->sign = ' ', \
  503. fos->ManLen = 1, \
  504. fos->man[0] = '0',\
  505. fos->man[1] = 0;
  506. #define SNAN_STR "1#SNAN"
  507. #define SNAN_STR_LEN 6
  508. #define QNAN_STR "1#QNAN"
  509. #define QNAN_STR_LEN 6
  510. #define INF_STR "1#INF"
  511. #define INF_STR_LEN 5
  512. #define IND_STR "1#IND"
  513. #define IND_STR_LEN 5
  514. /***
  515. char * _uldtoa (_ULDOUBLE *px,
  516. * int maxchars,
  517. * char *ldtext)
  518. *
  519. *
  520. *Purpose:
  521. * Return pointer to filled in string "ldtext" for
  522. * a given _UDOUBLE ponter px
  523. * with a maximum character width of maxchars
  524. *
  525. *Entry:
  526. * _ULDOUBLE * px: a pointer to the long double to be converted into a string
  527. * int maxchars: number of digits allowed in the output format.
  528. *
  529. * (default is 'e' format)
  530. *
  531. * char * ldtext: a pointer to the output string
  532. *
  533. *Exit:
  534. * returns pointer to the output string
  535. *
  536. *Exceptions:
  537. *
  538. *******************************************************************************/
  539. char * _uldtoa (_ULDOUBLE *px, int maxchars, char *ldtext)
  540. {
  541. char in_str[100];
  542. char in_str2[100];
  543. char cExp[100];
  544. FOS foss;
  545. char * lpszMan;
  546. char * lpIndx;
  547. int nErr;
  548. int len1, len2;
  549. maxchars -= 9; /* sign, dot, E+0001 */
  550. nErr = $I10_OUTPUT (*px, maxchars, 0, &foss);
  551. lpszMan = foss.man;
  552. ldtext[0] = foss.sign;
  553. ldtext[1] = *lpszMan;
  554. ldtext[2] = '.';
  555. ldtext[3] = '\0';
  556. maxchars += 2; /* sign, dot */
  557. lpszMan++;
  558. strcat (ldtext, lpszMan);
  559. len1 = strlen (ldtext); // for 'e'
  560. strcpy (cExp, "e");
  561. foss.exp -= 1; /* Adjust for the shift decimal shift above */
  562. _itoa (foss.exp, in_str, 10);
  563. if (foss.exp < 0) {
  564. strcat (cExp, "-");
  565. strcpy (in_str2, &in_str[1]);
  566. strcpy (in_str, in_str2);
  567. while (strlen(in_str) < 4) {
  568. strcpy (in_str2, in_str);
  569. strcpy (in_str,"0");
  570. strcat (in_str,in_str2);
  571. }
  572. } else {
  573. while (strlen(in_str) < 4) {
  574. strcpy (in_str2, in_str);
  575. strcpy (in_str,"0");
  576. strcat (in_str,in_str2);
  577. }
  578. }
  579. if (foss.exp >= 0) {
  580. strcat (cExp, "+");
  581. }
  582. strcat (cExp, in_str);
  583. len2 = strlen (cExp);
  584. if (len1 == maxchars) {
  585. ;
  586. }
  587. else if (len1 < maxchars) {
  588. do {
  589. strcat (ldtext,"0");
  590. len1++;
  591. } while (len1 < maxchars);
  592. }
  593. else {
  594. lpIndx = &ldtext[len1 - 1]; // point to last char and round
  595. do {
  596. *lpIndx = '\0';
  597. lpIndx--;
  598. len1--; //NOTENOTE v-griffk we really need to round
  599. } while (len1 > maxchars);
  600. }
  601. strcat (ldtext, cExp);
  602. return ldtext;
  603. }
  604. /***
  605. *int _$i10_output(_ULDOUBLE ld,
  606. * int ndigits,
  607. * unsigned output_flags,
  608. * FOS *fos) - output conversion of a 10-byte _ULDOUBLE
  609. *
  610. *Purpose:
  611. * Fill in a FOS structure for a given _ULDOUBLE
  612. *
  613. *Entry:
  614. * _ULDOUBLE ld: The long double to be converted into a string
  615. * int ndigits: number of digits allowed in the output format.
  616. * unsigned output_flags: The following flags can be used:
  617. * SO_FFORMAT: Indicates 'f' format
  618. * (default is 'e' format)
  619. * FOS *fos: the structure that i10_output will fill in
  620. *
  621. *Exit:
  622. * modifies *fos
  623. * return 1 if original number was ok, 0 otherwise (infinity, NaN, etc)
  624. *
  625. *Exceptions:
  626. *
  627. *******************************************************************************/
  628. int $I10_OUTPUT(_ULDOUBLE ld, int ndigits,
  629. unsigned output_flags, FOS *fos)
  630. {
  631. u_short expn;
  632. u_long manhi,manlo;
  633. u_short sign;
  634. /* useful constants (see algorithm explanation below) */
  635. u_short const log2hi = 0x4d10;
  636. u_short const log2lo = 0x4d;
  637. u_short const log4hi = 0x9a;
  638. u_long const c = 0x134312f4;
  639. #if defined(L_END)
  640. _ULDBL12 ld12_one_tenth = {
  641. {0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,
  642. 0xcc,0xcc,0xcc,0xcc,0xfb,0x3f}
  643. };
  644. #elif defined(B_END)
  645. _ULDBL12 ld12_one_tenth = {
  646. {0x3f,0xfb,0xcc,0xcc,0xcc,0xcc,
  647. 0xcc,0xcc,0xcc,0xcc,0xcc,0xcc}
  648. };
  649. #endif
  650. _ULDBL12 ld12; /* space for a 12-byte long double */
  651. _ULDBL12 tmp12;
  652. u_short hh,ll; /* the bytes of the exponent grouped in 2 words*/
  653. u_short mm; /* the two MSBytes of the mantissa */
  654. s_long r; /* the corresponding power of 10 */
  655. s_short ir; /* ir = floor(r) */
  656. int retval = 1; /* assume valid number */
  657. char round; /* an additional character at the end of the string */
  658. char *p;
  659. int i;
  660. int ub_exp;
  661. int digcount;
  662. /* grab the components of the long double */
  663. expn = *U_EXP_LD(&ld);
  664. manhi = *UL_MANHI_LD(&ld);
  665. manlo = *UL_MANLO_LD(&ld);
  666. sign = expn & MSB_USHORT;
  667. expn &= 0x7fff;
  668. if (sign)
  669. fos->sign = '-';
  670. else
  671. fos->sign = ' ';
  672. if (expn==0 && manhi==0 && manlo==0) {
  673. PUT_ZERO_FOS(fos);
  674. return 1;
  675. }
  676. if (expn == 0x7fff) {
  677. fos->exp = 1; /* set a positive exponent for proper output */
  678. /* check for special cases */
  679. if (_IS_MAN_SNAN(sign, manhi, manlo)) {
  680. /* signaling NAN */
  681. STRCPY(fos->man,SNAN_STR);
  682. fos->ManLen = SNAN_STR_LEN;
  683. retval = 0;
  684. }
  685. else if (_IS_MAN_IND(sign, manhi, manlo)) {
  686. /* indefinite */
  687. STRCPY(fos->man,IND_STR);
  688. fos->ManLen = IND_STR_LEN;
  689. retval = 0;
  690. }
  691. else if (_IS_MAN_INF(sign, manhi, manlo)) {
  692. /* infinity */
  693. STRCPY(fos->man,INF_STR);
  694. fos->ManLen = INF_STR_LEN;
  695. retval = 0;
  696. }
  697. else {
  698. /* quiet NAN */
  699. STRCPY(fos->man,QNAN_STR);
  700. fos->ManLen = QNAN_STR_LEN;
  701. retval = 0;
  702. }
  703. }
  704. else {
  705. /*
  706. * Algorithm for the decoding of a valid real number x
  707. *
  708. * In the following INT(r) is the largest integer less than or
  709. * equal to r (i.e. r rounded toward -infinity). We want a result
  710. * r equal to 1 + log(x), because then x = mantissa
  711. * * 10^(INT(r)) so that .1 <= mantissa < 1. Unfortunately,
  712. * we cannot compute s exactly so we must alter the procedure
  713. * slightly. We will instead compute an estimate r of 1 +
  714. * log(x) which is always low. This will either result
  715. * in the correctly normalized number on the top of the stack
  716. * or perhaps a number which is a factor of 10 too large. We
  717. * will then check to see that if x is larger than one
  718. * and if so multiply x by 1/10.
  719. *
  720. * We will use a low precision (fixed point 24 bit) estimate
  721. * of of 1 + log base 10 of x. We have approximately .mm
  722. * * 2^hhll on the top of the stack where m, h, and l represent
  723. * hex digits, mm represents the high 2 hex digits of the
  724. * mantissa, hh represents the high 2 hex digits of the exponent,
  725. * and ll represents the low 2 hex digits of the exponent. Since
  726. * .mm is a truncated representation of the mantissa, using it
  727. * in this monotonically increasing polynomial approximation
  728. * of the logarithm will naturally give a low result. Let's
  729. * derive a formula for a lower bound r on 1 + log(x):
  730. *
  731. * .4D104D42H < log(2)=.30102999...(base 10) < .4D104D43H
  732. * .9A20H < log(4)=.60205999...(base 10) < .9A21H
  733. *
  734. * 1/2 <= .mm < 1
  735. * ==> log(.mm) >= .mm * log(4) - log(4)
  736. *
  737. * Substituting in truncated hex constants in the formula above
  738. * gives r = 1 + .4D104DH * hhll. + .9AH * .mm - .9A21H. Now
  739. * multiplication of hex digits 5 and 6 of log(2) by ll has an
  740. * insignificant effect on the first 24 bits of the result so
  741. * it will not be calculated. This gives the expression r =
  742. * 1 + .4D10H * hhll. + .4DH * .hh + .9A * .mm - .9A21H.
  743. * Finally we must add terms to our formula to subtract out the
  744. * effect of the exponent bias. We obtain the following formula:
  745. *
  746. * (implied decimal point)
  747. * < >.< >
  748. * |3|3|2|2|2|2|2|2|2|2|2|2|1|1|1|1|1|1|1|1|1|1|0|0|0|0|0|0|0|0|0|0|
  749. * |1|0|9|8|7|6|5|4|3|2|1|0|9|8|7|6|5|4|3|2|1|0|9|8|7|6|5|4|3|2|1|0|
  750. * + < 1 >
  751. * + < .4D10H * hhll. >
  752. * + < .00004DH * hh00. >
  753. * + < .9AH * .mm >
  754. * - < .9A21H >
  755. * - < .4D10H * 3FFEH >
  756. * - < .00004DH * 3F00H >
  757. *
  758. * ==> r = .4D10H * hhll. + .4DH * .hh + .9AH * .mm - 1343.12F4H
  759. *
  760. * The difference between the lower bound r and the upper bound
  761. * s is calculated as follows:
  762. *
  763. * .937EH < 1/ln(10)-log(1/ln(4))=.57614993...(base 10) < .937FH
  764. *
  765. * 1/2 <= .mm < 1
  766. * ==> log(.mm) <= .mm * log(4) - [1/ln(10) - log(1/ln(4))]
  767. *
  768. * so tenatively s = r + log(4) - [1/ln(10) - log(1/ln(4))],
  769. * but we must also add in terms to ensure we will have an upper
  770. * bound even after the truncation of various values. Because
  771. * log(2) * hh00. is truncated to .4D104DH * hh00. we must
  772. * add .0043H, because log(2) * ll. is truncated to .4D10H *
  773. * ll. we must add .0005H, because <mantissa> * log(4) is
  774. * truncated to .mm * .9AH we must add .009AH and .0021H.
  775. *
  776. * Thus s = r - .937EH + .9A21H + .0043H + .0005H + .009AH + .0021H
  777. * = r + .07A6H
  778. * ==> s = .4D10H * hhll. + .4DH * .hh + .9AH * .mm - 1343.0B4EH
  779. *
  780. * r is equal to 1 + log(x) more than (10000H - 7A6H) /
  781. * 10000H = 97% of the time.
  782. *
  783. * In the above formula, a u_long is use to accomodate r, and
  784. * there is an implied decimal point in the middle.
  785. */
  786. hh = expn >> 8;
  787. ll = expn & (u_short)0xff;
  788. mm = (u_short) (manhi >> 24);
  789. r = (s_long)log2hi*(s_long)expn + log2lo*hh + log4hi*mm - c;
  790. ir = (s_short)(r >> 16);
  791. /*
  792. *
  793. * We stated that we wanted to normalize x so that
  794. *
  795. * .1 <= x < 1
  796. *
  797. * This was a slight oversimplification. Actually we want a
  798. * number which when rounded to 16 significant digits is in the
  799. * desired range. To do this we must normalize x so that
  800. *
  801. * .1 - 5*10^(-18) <= x < 1 - 5*10^(-17)
  802. *
  803. * and then round.
  804. *
  805. * If we had f = INT(1+log(x)) we could multiply by 10^(-f)
  806. * to get x into the desired range. We do not quite have
  807. * f but we do have INT(r) from the last step which is equal
  808. * to f 97% of the time and 1 less than f the rest of the time.
  809. * We can multiply by 10^-[INT(r)] and if the result is greater
  810. * than 1 - 5*10^(-17) we can then multiply by 1/10. This final
  811. * result will lie in the proper range.
  812. */
  813. /* convert _ULDOUBLE to _ULDBL12) */
  814. *U_EXP_12(&ld12) = expn;
  815. *UL_MANHI_12(&ld12) = manhi;
  816. *UL_MANLO_12(&ld12) = manlo;
  817. *U_XT_12(&ld12) = 0;
  818. /* multiply by 10^(-ir) */
  819. __multtenpow12(&ld12,-ir,1);
  820. /* if ld12 >= 1.0 then divide by 10.0 */
  821. if (*U_EXP_12(&ld12) >= 0x3fff) {
  822. ir++;
  823. __ld12mul(&ld12,&ld12_one_tenth);
  824. }
  825. fos->exp = ir;
  826. if (output_flags & SO_FFORMAT){
  827. /* 'f' format, add exponent to ndigits */
  828. ndigits += ir;
  829. if (ndigits <= 0) {
  830. /* return 0 */
  831. PUT_ZERO_FOS(fos);
  832. return 1;
  833. }
  834. }
  835. if (ndigits > MAX_MAN_DIGITS)
  836. ndigits = MAX_MAN_DIGITS;
  837. ub_exp = *U_EXP_12(&ld12) - 0x3ffe; /* unbias exponent */
  838. *U_EXP_12(&ld12) = 0;
  839. /*
  840. * Now the mantissa has to be converted to fixed point.
  841. * Then we will use the MSB of ld12 for generating
  842. * the decimal digits. The next 11 bytes will hold
  843. * the mantissa (after it has been converted to
  844. * fixed point).
  845. */
  846. for (i=0;i<8;i++)
  847. __shl_12(&ld12); /* make space for an extra byte,
  848. in case we shift right later */
  849. if (ub_exp < 0) {
  850. int shift_count = (-ub_exp) & 0xff;
  851. for (;shift_count>0;shift_count--)
  852. __shr_12(&ld12);
  853. }
  854. p = fos->man;
  855. for(digcount=ndigits+1;digcount>0;digcount--) {
  856. tmp12 = ld12;
  857. __shl_12(&ld12);
  858. __shl_12(&ld12);
  859. __add_12(&ld12,&tmp12);
  860. __shl_12(&ld12); /* ld12 *= 10 */
  861. /* Now we have the first decimal digit in the msbyte of exponent */
  862. *p++ = (char) (*UCHAR_12(&ld12,11) + '0');
  863. *UCHAR_12(&ld12,11) = 0;
  864. }
  865. round = *(--p);
  866. p--; /* p points now to the last character of the string
  867. excluding the rounding digit */
  868. if (round >= '5') {
  869. /* look for a non-9 digit starting from the end of string */
  870. for (;p>=fos->man && *p=='9';p--) {
  871. *p = '0';
  872. }
  873. if (p < fos->man){
  874. p++;
  875. fos->exp ++;
  876. }
  877. (*p)++;
  878. }
  879. else {
  880. /* remove zeros */
  881. for (;p>=fos->man && *p=='0';p--);
  882. if (p < fos->man) {
  883. /* return 0 */
  884. PUT_ZERO_FOS(fos);
  885. return 1;
  886. }
  887. }
  888. fos->ManLen = (char) (p - fos->man + 1);
  889. fos->man[fos->ManLen] = '\0';
  890. }
  891. return retval;
  892. }
  893. /***
  894. *strgtold.c - conversion of a string into a long double
  895. *
  896. * Copyright (c) 1991-1991, Microsoft Corporation. All rights reserved.
  897. *
  898. *Purpose: convert a fp constant into a 10 byte long double (IEEE format)
  899. *
  900. *Revision History:
  901. * 7-17-91 GDP Initial version (ported from assembly)
  902. * 4-03-92 GDP Preserve sign of -0
  903. * 4-30-92 GDP Now returns _ULDBL12 instead of _ULDOUBLE
  904. * 05-26-92 GWK Windbg srcs
  905. *
  906. *******************************************************************************/
  907. /* local macros */
  908. #define ISNZDIGIT(x) ((x)>='1' && (x)<='9' )
  909. //NOTENOTE the following takes the place of the isdigit() macro
  910. // which does not work for a yet to be determined reason
  911. #define ISADIGIT(x) ((x)>='0' && (x)<='9' )
  912. #define ISWHITE(x) ((x)==' ' || (x)=='\t' || (x)=='\n' || (x)=='\r' )
  913. /****
  914. *unsigned int __strgtold( _ULDBL12 *pld12,
  915. * char * * pEndPtr,
  916. * char * str,
  917. * int Mult12 )
  918. *
  919. *Purpose:
  920. * converts a character string into a long double
  921. *
  922. *Entry:
  923. * pld12 - pointer to the _ULDBL12 where the result should go.
  924. * pEndStr - pointer to a far pointer that will be set to the end of string.
  925. * str - pointer to the string to be converted.
  926. * Mult12 - set to non zero if the _ULDBL12 multiply should be used instead of
  927. * the long double mulitiply.
  928. *
  929. *Exit:
  930. * Returns the SLD_* flags or'ed together.
  931. *
  932. *Uses:
  933. *
  934. *Exceptions:
  935. *
  936. ********************************************************************************/
  937. unsigned int
  938. __strgtold12(_ULDBL12 *pld12,
  939. char * *p_end_ptr,
  940. char *str,
  941. int mult12)
  942. {
  943. typedef enum {
  944. S_INIT, /* initial state */
  945. S_EAT0L, /* eat 0's at the left of mantissa */
  946. S_SIGNM, /* just read sign of mantissa */
  947. S_GETL, /* get integer part of mantissa */
  948. S_GETR, /* get decimal part of mantissa */
  949. S_POINT, /* just found decimal point */
  950. S_E, /* just found 'E', or 'e', etc */
  951. S_SIGNE, /* just read sign of exponent */
  952. S_EAT0E, /* eat 0's at the left of exponent */
  953. S_GETE, /* get exponent */
  954. S_END /* final state */
  955. } state_t;
  956. /* this will accomodate the digits of the mantissa in BCD form*/
  957. static char buf[LD_MAX_MAN_LEN1];
  958. char *manp = buf;
  959. /* a temporary _ULDBL12 */
  960. _ULDBL12 tmpld12;
  961. u_short man_sign = 0; /* to be ORed with result */
  962. int exp_sign = 1; /* default sign of exponent (values: +1 or -1)*/
  963. /* number of decimal significant mantissa digits so far*/
  964. unsigned manlen = 0;
  965. int found_digit = 0;
  966. int overflow = 0;
  967. int underflow = 0;
  968. int pow = 0;
  969. int exp_adj = 0; /* exponent adjustment */
  970. u_long ul0,ul1;
  971. u_short u,uexp;
  972. unsigned int result_flags = 0;
  973. state_t state = S_INIT;
  974. char c; /* the current input symbol */
  975. char *p; /* a pointer to the next input symbol */
  976. char *savedp;
  977. for(savedp=p=str;ISWHITE(*p);p++); /* eat up white space */
  978. while (state != S_END) {
  979. c = *p++;
  980. switch (state) {
  981. case S_INIT:
  982. if (ISNZDIGIT(c)) {
  983. state = S_GETL;
  984. p--;
  985. }
  986. else
  987. switch (c) {
  988. case '0':
  989. state = S_EAT0L;
  990. break;
  991. case '+':
  992. state = S_SIGNM;
  993. man_sign = 0x0000;
  994. break;
  995. case '-':
  996. state = S_SIGNM;
  997. man_sign = 0x8000;
  998. break;
  999. case '.':
  1000. state = S_POINT;
  1001. break;
  1002. default:
  1003. state = S_END;
  1004. p--;
  1005. break;
  1006. }
  1007. break;
  1008. case S_EAT0L:
  1009. found_digit = 1;
  1010. if (ISNZDIGIT(c)) {
  1011. state = S_GETL;
  1012. p--;
  1013. }
  1014. else
  1015. switch (c) {
  1016. case '0':
  1017. state = S_EAT0L;
  1018. break;
  1019. case 'E':
  1020. case 'e':
  1021. case 'D':
  1022. case 'd':
  1023. state = S_E;
  1024. break;
  1025. case '.':
  1026. state = S_GETR;
  1027. break;
  1028. default:
  1029. state = S_END;
  1030. p--;
  1031. }
  1032. break;
  1033. case S_SIGNM:
  1034. if (ISNZDIGIT(c)) {
  1035. state = S_GETL;
  1036. p--;
  1037. }
  1038. else
  1039. switch (c) {
  1040. case '0':
  1041. state = S_EAT0L;
  1042. break;
  1043. case '.':
  1044. state = S_POINT;
  1045. break;
  1046. default:
  1047. state = S_END;
  1048. p = savedp;
  1049. }
  1050. break;
  1051. case S_GETL:
  1052. found_digit = 1;
  1053. for (;ISADIGIT(c);c=*p++) {
  1054. if (manlen < LD_MAX_MAN_LEN+1){
  1055. manlen++;
  1056. *manp++ = c - (char)'0';
  1057. }
  1058. else
  1059. exp_adj++;
  1060. }
  1061. switch (c) {
  1062. case '.':
  1063. state = S_GETR;
  1064. break;
  1065. case 'E':
  1066. case 'e':
  1067. case 'D':
  1068. case 'd':
  1069. state = S_E;
  1070. break;
  1071. default:
  1072. state = S_END;
  1073. p--;
  1074. }
  1075. break;
  1076. case S_GETR:
  1077. found_digit = 1;
  1078. if (manlen == 0)
  1079. for (;c=='0';c=*p++)
  1080. exp_adj--;
  1081. for(;ISADIGIT(c);c=*p++){
  1082. if (manlen < LD_MAX_MAN_LEN+1){
  1083. manlen++;
  1084. *manp++ = c - (char)'0';
  1085. exp_adj--;
  1086. }
  1087. }
  1088. switch (c){
  1089. case 'E':
  1090. case 'e':
  1091. case 'D':
  1092. case 'd':
  1093. state = S_E;
  1094. break;
  1095. default:
  1096. state = S_END;
  1097. p--;
  1098. }
  1099. break;
  1100. case S_POINT:
  1101. if (ISADIGIT(c)){
  1102. state = S_GETR;
  1103. p--;
  1104. }
  1105. else{
  1106. state = S_END;
  1107. p = savedp;
  1108. }
  1109. break;
  1110. case S_E:
  1111. savedp = p-2; /* savedp points to 'E' */
  1112. if (ISNZDIGIT(c)){
  1113. state = S_GETE;
  1114. p--;
  1115. }
  1116. else
  1117. switch (c){
  1118. case '0':
  1119. state = S_EAT0E;
  1120. break;
  1121. case '-':
  1122. state = S_SIGNE;
  1123. exp_sign = -1;
  1124. break;
  1125. case '+':
  1126. state = S_SIGNE;
  1127. break;
  1128. default:
  1129. state = S_END;
  1130. p = savedp;
  1131. }
  1132. break;
  1133. case S_EAT0E:
  1134. for(;c=='0';c=*p++);
  1135. if (ISNZDIGIT(c)){
  1136. state = S_GETE;
  1137. p--;
  1138. }
  1139. else {
  1140. state = S_END;
  1141. p--;
  1142. }
  1143. break;
  1144. case S_SIGNE:
  1145. if (ISNZDIGIT(c)){
  1146. state = S_GETE;
  1147. p--;
  1148. }
  1149. else
  1150. switch (c){
  1151. case '0':
  1152. state = S_EAT0E;
  1153. break;
  1154. default:
  1155. state = S_END;
  1156. p = savedp;
  1157. }
  1158. break;
  1159. case S_GETE:
  1160. {
  1161. long longpow=0; /* TMAX10*10 should fit in a long */
  1162. for(;ISADIGIT(c);c=*p++){
  1163. longpow = longpow*10 + (c - '0');
  1164. if (longpow > TMAX10){
  1165. longpow = TMAX10+1; /* will force overflow */
  1166. break;
  1167. }
  1168. }
  1169. pow = (int)longpow;
  1170. }
  1171. for(;ISADIGIT(c);c=*p++); /* eat up remaining digits */
  1172. state = S_END;
  1173. p--;
  1174. break;
  1175. } /* switch */
  1176. } /* while */
  1177. *p_end_ptr = p; /* set end pointer */
  1178. /*
  1179. * Compute result
  1180. */
  1181. if (found_digit && !overflow && !underflow) {
  1182. if (manlen>LD_MAX_MAN_LEN){
  1183. if (buf[LD_MAX_MAN_LEN-1]>=5) {
  1184. /*
  1185. * Round mantissa to MAX_MAN_LEN digits
  1186. * It's ok to round 9 to 0ah
  1187. */
  1188. buf[LD_MAX_MAN_LEN-1]++;
  1189. }
  1190. manlen = LD_MAX_MAN_LEN;
  1191. manp--;
  1192. exp_adj++;
  1193. }
  1194. if (manlen>0) {
  1195. /*
  1196. * Remove trailing zero's from mantissa
  1197. */
  1198. for(manp--;*manp==0;manp--) {
  1199. /* there is at least one non-zero digit */
  1200. manlen--;
  1201. exp_adj++;
  1202. }
  1203. __mtold12(buf,manlen,&tmpld12);
  1204. if (exp_sign < 0)
  1205. pow = -pow;
  1206. pow += exp_adj;
  1207. if (pow > TMAX10)
  1208. overflow = 1;
  1209. else if (pow < TMIN10)
  1210. underflow = 1;
  1211. else {
  1212. __multtenpow12(&tmpld12,pow,mult12);
  1213. u = *U_XT_12(&tmpld12);
  1214. ul0 =*UL_MANLO_12(&tmpld12);
  1215. ul1 = *UL_MANHI_12(&tmpld12);
  1216. uexp = *U_EXP_12(&tmpld12);
  1217. }
  1218. }
  1219. else {
  1220. /* manlen == 0, so return 0 */
  1221. u = (u_short)0;
  1222. ul0 = ul1 = uexp = 0;
  1223. }
  1224. }
  1225. if (!found_digit) {
  1226. /* return 0 */
  1227. u = (u_short)0;
  1228. ul0 = ul1 = uexp = 0;
  1229. result_flags |= SLD_NODIGITS;
  1230. }
  1231. else if (overflow) {
  1232. /* return +inf or -inf */
  1233. uexp = (u_short)0x7fff;
  1234. ul1 = 0x80000000;
  1235. ul0 = 0;
  1236. u = (u_short)0;
  1237. result_flags |= SLD_OVERFLOW;
  1238. }
  1239. else if (underflow) {
  1240. /* return 0 */
  1241. u = (u_short)0;
  1242. ul0 = ul1 = uexp = 0;
  1243. result_flags |= SLD_UNDERFLOW;
  1244. }
  1245. /*
  1246. * Assemble result
  1247. */
  1248. *U_XT_12(pld12) = u;
  1249. *UL_MANLO_12(pld12) = ul0;
  1250. *UL_MANHI_12(pld12) = ul1;
  1251. *U_EXP_12(pld12) = uexp | man_sign;
  1252. return result_flags;
  1253. }
  1254. /***
  1255. * intrncvt.c - internal floating point conversions
  1256. *
  1257. * Copyright (c) 1992-1992, Microsoft Corporation. All rights reserved.
  1258. *
  1259. *Purpose:
  1260. * All fp string conversion routines use the same core conversion code
  1261. * that converts strings into an internal long double representation
  1262. * with an 80-bit mantissa field. The mantissa is represented
  1263. * as an array (man) of 32-bit unsigned longs, with man[0] holding
  1264. * the high order 32 bits of the mantissa. The binary point is assumed
  1265. * to be between the MSB and MSB-1 of man[0].
  1266. *
  1267. * Bits are counted as follows:
  1268. *
  1269. *
  1270. * +-- binary point
  1271. * |
  1272. * v MSB LSB
  1273. * ---------------- ------------------ --------------------
  1274. * |0 1 .... 31| | 32 33 ... 63| | 64 65 ... 95|
  1275. * ---------------- ------------------ --------------------
  1276. *
  1277. * man[0] man[1] man[2]
  1278. *
  1279. * This file provides the final conversion routines from this internal
  1280. * form to the single, double, or long double precision floating point
  1281. * format.
  1282. *
  1283. * All these functions do not handle NaNs (it is not necessary)
  1284. *
  1285. *
  1286. *Revision History:
  1287. * 04-29-92 GDP written
  1288. * 05-26-92 GWK Windbg srcs
  1289. *
  1290. *******************************************************************************/
  1291. #define INTRNMAN_LEN 3 /* internal mantissa length in int's */
  1292. //
  1293. // internal mantissaa representation
  1294. // for string conversion routines
  1295. //
  1296. typedef u_long *intrnman;
  1297. typedef struct {
  1298. int max_exp; // maximum base 2 exponent (reserved for special values)
  1299. int min_exp; // minimum base 2 exponent (reserved for denormals)
  1300. int precision; // bits of precision carried in the mantissa
  1301. int exp_width; // number of bits for exponent
  1302. int format_width; // format width in bits
  1303. int bias; // exponent bias
  1304. } FpFormatDescriptor;
  1305. static FpFormatDescriptor
  1306. DoubleFormat = {
  1307. 0x7ff - 0x3ff, // 1024, maximum base 2 exponent (reserved for special values)
  1308. 0x0 - 0x3ff, // -1023, minimum base 2 exponent (reserved for denormals)
  1309. 53, // bits of precision carried in the mantissa
  1310. 11, // number of bits for exponent
  1311. 64, // format width in bits
  1312. 0x3ff, // exponent bias
  1313. };
  1314. static FpFormatDescriptor
  1315. FloatFormat = {
  1316. 0xff - 0x7f, // 128, maximum base 2 exponent (reserved for special values)
  1317. 0x0 - 0x7f, // -127, minimum base 2 exponent (reserved for denormals)
  1318. 24, // bits of precision carried in the mantissa
  1319. 8, // number of bits for exponent
  1320. 32, // format width in bits
  1321. 0x7f, // exponent bias
  1322. };
  1323. //
  1324. // function prototypes
  1325. //
  1326. int _RoundMan (intrnman man, int nbit);
  1327. int _ZeroTail (intrnman man, int nbit);
  1328. int _IncMan (intrnman man, int nbit);
  1329. void _CopyMan (intrnman dest, intrnman src);
  1330. void _CopyMan (intrnman dest, intrnman src);
  1331. void _FillZeroMan(intrnman man);
  1332. void _Shrman (intrnman man, int n);
  1333. INTRNCVT_STATUS _ld12cvt(_ULDBL12 *pld12, void *d, FpFormatDescriptor *format);
  1334. /***
  1335. * _ZeroTail - check if a mantissa ends in 0's
  1336. *
  1337. *Purpose:
  1338. * Return TRUE if all mantissa bits after nbit (including nbit) are 0,
  1339. * otherwise return FALSE
  1340. *
  1341. *
  1342. *Entry:
  1343. * man: mantissa
  1344. * nbit: order of bit where the tail begins
  1345. *
  1346. *Exit:
  1347. *
  1348. *Exceptions:
  1349. *
  1350. *******************************************************************************/
  1351. int _ZeroTail (intrnman man, int nbit)
  1352. {
  1353. int nl = nbit / 32;
  1354. int nb = 31 - nbit % 32;
  1355. //
  1356. // |<---- tail to be checked --->
  1357. //
  1358. // -- ------------------------ ----
  1359. // |... | | ... |
  1360. // -- ------------------------ ----
  1361. // ^ ^ ^
  1362. // | | |<----nb----->
  1363. // man nl nbit
  1364. //
  1365. u_long bitmask = ~(MAX_ULONG << nb);
  1366. if (man[nl] & bitmask)
  1367. return 0;
  1368. nl++;
  1369. for (;nl < INTRNMAN_LEN; nl++)
  1370. if (man[nl])
  1371. return 0;
  1372. return 1;
  1373. }
  1374. /***
  1375. * _IncMan - increment mantissa
  1376. *
  1377. *Purpose:
  1378. *
  1379. *
  1380. *Entry:
  1381. * man: mantissa in internal long form
  1382. * nbit: order of bit that specifies the end of the part to be incremented
  1383. *
  1384. *Exit:
  1385. * returns 1 on overflow, 0 otherwise
  1386. *
  1387. *Exceptions:
  1388. *
  1389. *******************************************************************************/
  1390. int _IncMan (intrnman man, int nbit)
  1391. {
  1392. int nl = nbit / 32;
  1393. int nb = 31 - nbit % 32;
  1394. //
  1395. // |<--- part to be incremented -->|
  1396. //
  1397. // -- --------------------------- ----
  1398. // |... | | ... |
  1399. // -- --------------------------- ----
  1400. // ^ ^ ^
  1401. // | | |<--nb-->
  1402. // man nl nbit
  1403. //
  1404. u_long one = (u_long) 1 << nb;
  1405. int carry;
  1406. carry = __addl(man[nl], one, &man[nl]);
  1407. nl--;
  1408. for (; nl >= 0 && carry; nl--) {
  1409. carry = (u_long) __addl(man[nl], (u_long) 1, &man[nl]);
  1410. }
  1411. return carry;
  1412. }
  1413. /***
  1414. * _RoundMan - round mantissa
  1415. *
  1416. *Purpose:
  1417. * round mantissa to nbit precision
  1418. *
  1419. *
  1420. *Entry:
  1421. * man: mantissa in internal form
  1422. * precision: number of bits to be kept after rounding
  1423. *
  1424. *Exit:
  1425. * returns 1 on overflow, 0 otherwise
  1426. *
  1427. *Exceptions:
  1428. *
  1429. *******************************************************************************/
  1430. int _RoundMan (intrnman man, int precision)
  1431. {
  1432. int i,rndbit,nl,nb;
  1433. u_long rndmask;
  1434. int nbit;
  1435. int retval = 0;
  1436. //
  1437. // The order of the n'th bit is n-1, since the first bit is bit 0
  1438. // therefore decrement precision to get the order of the last bit
  1439. // to be kept
  1440. //
  1441. nbit = precision - 1;
  1442. rndbit = nbit+1;
  1443. nl = rndbit / 32;
  1444. nb = 31 - rndbit % 32;
  1445. //
  1446. // Get value of round bit
  1447. //
  1448. rndmask = (u_long)1 << nb;
  1449. if ((man[nl] & rndmask) &&
  1450. !_ZeroTail(man, rndbit+1)) {
  1451. //
  1452. // round up
  1453. //
  1454. retval = _IncMan(man, nbit);
  1455. }
  1456. //
  1457. // fill rest of mantissa with zeroes
  1458. //
  1459. man[nl] &= MAX_ULONG << nb;
  1460. for(i=nl+1; i<INTRNMAN_LEN; i++) {
  1461. man[i] = (u_long)0;
  1462. }
  1463. return retval;
  1464. }
  1465. /***
  1466. * _CopyMan - copy mantissa
  1467. *
  1468. *Purpose:
  1469. * copy src to dest
  1470. *
  1471. *Entry:
  1472. *
  1473. *Exit:
  1474. *
  1475. *Exceptions:
  1476. *
  1477. *******************************************************************************/
  1478. void _CopyMan (intrnman dest, intrnman src)
  1479. {
  1480. u_long *p, *q;
  1481. int i;
  1482. p = src;
  1483. q = dest;
  1484. for (i=0; i < INTRNMAN_LEN; i++) {
  1485. *q++ = *p++;
  1486. }
  1487. }
  1488. /***
  1489. * _FillZeroMan - fill mantissa with zeroes
  1490. *
  1491. *Purpose:
  1492. *
  1493. *
  1494. *Entry:
  1495. *
  1496. *Exit:
  1497. *
  1498. *Exceptions:
  1499. *
  1500. *******************************************************************************/
  1501. void _FillZeroMan(intrnman man)
  1502. {
  1503. int i;
  1504. for (i=0; i < INTRNMAN_LEN; i++)
  1505. man[i] = (u_long)0;
  1506. }
  1507. /***
  1508. * _IsZeroMan - check if mantissa is zero
  1509. *
  1510. *Purpose:
  1511. *
  1512. *
  1513. *Entry:
  1514. *
  1515. *Exit:
  1516. *
  1517. *Exceptions:
  1518. *
  1519. *******************************************************************************/
  1520. int _IsZeroMan(intrnman man)
  1521. {
  1522. int i;
  1523. for (i=0; i < INTRNMAN_LEN; i++)
  1524. if (man[i])
  1525. return 0;
  1526. return 1;
  1527. }
  1528. /***
  1529. * _ShrMan - shift mantissa to the right
  1530. *
  1531. *Purpose:
  1532. * shift man by n bits to the right
  1533. *
  1534. *Entry:
  1535. *
  1536. *Exit:
  1537. *
  1538. *Exceptions:
  1539. *
  1540. *******************************************************************************/
  1541. void _ShrMan (intrnman man, int n)
  1542. {
  1543. int i, n1, n2, mask;
  1544. int carry_from_left;
  1545. //
  1546. // declare this as volatile in order to work around a C8
  1547. // optimization bug
  1548. //
  1549. volatile int carry_to_right;
  1550. n1 = n / 32;
  1551. n2 = n % 32;
  1552. mask = ~(MAX_ULONG << n2);
  1553. //
  1554. // first deal with shifts by less than 32 bits
  1555. //
  1556. carry_from_left = 0;
  1557. for (i=0; i<INTRNMAN_LEN; i++) {
  1558. carry_to_right = man[i] & mask;
  1559. man[i] >>= n2;
  1560. man[i] |= carry_from_left;
  1561. carry_from_left = carry_to_right << (32 - n2);
  1562. }
  1563. //
  1564. // now shift whole 32-bit ints
  1565. //
  1566. for (i=INTRNMAN_LEN-1; i>=0; i--) {
  1567. if (i >= n1) {
  1568. man[i] = man[i-n1];
  1569. }
  1570. else {
  1571. man[i] = 0;
  1572. }
  1573. }
  1574. }
  1575. /***
  1576. * _ld12tocvt - _ULDBL12 floating point conversion
  1577. *
  1578. *Purpose:
  1579. * convert a internal _LBL12 structure into an IEEE floating point
  1580. * representation
  1581. *
  1582. *
  1583. *Entry:
  1584. * pld12: pointer to the _ULDBL12
  1585. * format: pointer to the format descriptor structure
  1586. *
  1587. *Exit:
  1588. * *d contains the IEEE representation
  1589. * returns the INTRNCVT_STATUS
  1590. *
  1591. *Exceptions:
  1592. *
  1593. *******************************************************************************/
  1594. INTRNCVT_STATUS _ld12cvt(_ULDBL12 *pld12, void *d, FpFormatDescriptor *format)
  1595. {
  1596. u_long man[INTRNMAN_LEN];
  1597. u_long saved_man[INTRNMAN_LEN];
  1598. u_long msw;
  1599. unsigned int bexp; // biased exponent
  1600. int exp_shift;
  1601. int exponent, sign;
  1602. INTRNCVT_STATUS retval;
  1603. exponent = (*U_EXP_12(pld12) & 0x7fff) - 0x3fff; // unbias exponent
  1604. sign = *U_EXP_12(pld12) & 0x8000;
  1605. //
  1606. // bexp is the final biased value of the exponent to be used
  1607. // Each of the following blocks should provide appropriate
  1608. // values for man, bexp and retval. The mantissa is also
  1609. // shifted to the right, leaving space for the exponent
  1610. // and sign to be inserted
  1611. //
  1612. if (exponent == 0 - 0x3fff) {
  1613. // either a denormal or zero
  1614. bexp = 0;
  1615. _FillZeroMan(man);
  1616. if (ISZERO_12(pld12)) {
  1617. retval = INTRNCVT_OK;
  1618. }
  1619. else {
  1620. // denormal has been flushed to zero
  1621. retval = INTRNCVT_UNDERFLOW;
  1622. }
  1623. }
  1624. else {
  1625. man[0] = *UL_MANHI_12(pld12);
  1626. man[1] = *UL_MANLO_12(pld12);
  1627. man[2] = *U_XT_12(pld12) << 16;
  1628. // save mantissa in case it needs to be rounded again
  1629. // at a different point (e.g., if the result is a denormal)
  1630. _CopyMan(saved_man, man);
  1631. if (_RoundMan(man, format->precision)) {
  1632. exponent ++;
  1633. }
  1634. if (exponent < format->min_exp - format->precision ) {
  1635. //
  1636. // underflow that produces a zero
  1637. //
  1638. _FillZeroMan(man);
  1639. bexp = 0;
  1640. retval = INTRNCVT_UNDERFLOW;
  1641. }
  1642. else if (exponent <= format->min_exp) {
  1643. //
  1644. // underflow that produces a denormal
  1645. //
  1646. //
  1647. // The (unbiased) exponent will be MIN_EXP
  1648. // Find out how much the mantissa should be shifted
  1649. // One shift is done implicitly by moving the
  1650. // binary point one bit to the left, i.e.,
  1651. // we treat the mantissa as .ddddd instead of d.dddd
  1652. // (where d is a binary digit)
  1653. int shift = format->min_exp - exponent;
  1654. // The mantissa should be rounded again, so it
  1655. // has to be restored
  1656. _CopyMan(man,saved_man);
  1657. _ShrMan(man, shift);
  1658. _RoundMan(man, format->precision); // need not check for carry
  1659. // make room for the exponent + sign
  1660. _ShrMan(man, format->exp_width + 1);
  1661. bexp = 0;
  1662. retval = INTRNCVT_UNDERFLOW;
  1663. }
  1664. else if (exponent >= format->max_exp) {
  1665. //
  1666. // overflow, return infinity
  1667. //
  1668. _FillZeroMan(man);
  1669. man[0] |= (1 << 31); // set MSB
  1670. // make room for the exponent + sign
  1671. _ShrMan(man, (format->exp_width + 1) - 1);
  1672. bexp = format->max_exp + format->bias;
  1673. retval = INTRNCVT_OVERFLOW;
  1674. }
  1675. else {
  1676. //
  1677. // valid, normalized result
  1678. //
  1679. bexp = exponent + format->bias;
  1680. // clear implied bit
  1681. man[0] &= (~( 1 << 31));
  1682. //
  1683. // shift right to make room for exponent + sign
  1684. //
  1685. _ShrMan(man, (format->exp_width + 1) - 1);
  1686. retval = INTRNCVT_OK;
  1687. }
  1688. }
  1689. exp_shift = 32 - (format->exp_width + 1);
  1690. msw = man[0] |
  1691. (bexp << exp_shift) |
  1692. (sign ? 1<<31 : 0);
  1693. if (format->format_width == 64) {
  1694. *UL_HI_D(d) = msw;
  1695. *UL_LO_D(d) = man[1];
  1696. }
  1697. else if (format->format_width == 32) {
  1698. *(u_long *)d = msw;
  1699. }
  1700. return retval;
  1701. }
  1702. /***
  1703. * _ld12tod - convert _ULDBL12 to double
  1704. *
  1705. *Purpose:
  1706. *
  1707. *
  1708. *Entry:
  1709. *
  1710. *Exit:
  1711. *
  1712. *Exceptions:
  1713. *
  1714. *******************************************************************************/
  1715. INTRNCVT_STATUS _ld12tod(_ULDBL12 *pld12, UDOUBLE *d)
  1716. {
  1717. return _ld12cvt(pld12, d, &DoubleFormat);
  1718. }
  1719. /***
  1720. * _ld12tof - convert _ULDBL12 to float
  1721. *
  1722. *Purpose:
  1723. *
  1724. *
  1725. *Entry:
  1726. *
  1727. *Exit:
  1728. *
  1729. *Exceptions:
  1730. *
  1731. *******************************************************************************/
  1732. INTRNCVT_STATUS _ld12tof(_ULDBL12 *pld12, FLOAT *f)
  1733. {
  1734. return _ld12cvt(pld12, f, &FloatFormat);
  1735. }
  1736. /***
  1737. * _ld12told - convert _ULDBL12 to 80 bit long double
  1738. *
  1739. *******************************************************************************/
  1740. void _ld12told(_ULDBL12 *pld12, _ULDOUBLE *pld)
  1741. {
  1742. //
  1743. // This implementation is based on the fact that the _ULDBL12 format is
  1744. // identical to the long double and has 2 extra bytes of mantissa
  1745. //
  1746. u_short exp, sign;
  1747. u_long man[INTRNMAN_LEN];
  1748. exp = *U_EXP_12(pld12) & (u_short)0x7fff;
  1749. sign = *U_EXP_12(pld12) & (u_short)0x8000;
  1750. man[0] = *UL_MANHI_12(pld12);
  1751. man[1] = *UL_MANLO_12(pld12);
  1752. man[2] = *U_XT_12(pld12) << 16;
  1753. if (_RoundMan(man, 64))
  1754. exp ++;
  1755. *UL_MANHI_LD(pld) = man[0];
  1756. *UL_MANLO_LD(pld) = man[1];
  1757. *U_EXP_LD(pld) = sign | exp;
  1758. }
  1759. /***
  1760. * _ldtold12 - convert _ULDOUBLE to _ULDBL12
  1761. *
  1762. *******************************************************************************/
  1763. void _ldtold12(_ULDOUBLE *pld, _ULDBL12 *pld12)
  1764. {
  1765. //
  1766. // This implementation is based on the fact that the _ULDBL12 format is
  1767. // identical to the long double and has 2 extra bytes of mantissa
  1768. //
  1769. memcpy(pld12, pld, 10);
  1770. *U_XT_12(pld12) = 0;
  1771. }
  1772. void _atodbl(UDOUBLE *d, char *str)
  1773. {
  1774. char *EndPtr;
  1775. _ULDBL12 ld12;
  1776. __strgtold12(&ld12, &EndPtr, str, 0 );
  1777. _ld12tod(&ld12, d);
  1778. }
  1779. void _atoldbl(_ULDOUBLE *ld, char *str)
  1780. {
  1781. char *EndPtr;
  1782. _ULDBL12 ld12;
  1783. __strgtold12(&ld12, &EndPtr, str, 0 );
  1784. _ld12told(&ld12, ld);
  1785. }
  1786. void _atoflt(FLOAT *f, char *str)
  1787. {
  1788. char *EndPtr;
  1789. _ULDBL12 ld12;
  1790. __strgtold12(&ld12, &EndPtr, str, 0 );
  1791. _ld12tof(&ld12, f);
  1792. }
  1793. double
  1794. Float82ToDouble(const FLOAT128* FpReg82)
  1795. {
  1796. double f = 0.0;
  1797. FLOAT82_FORMAT* f82 = (FLOAT82_FORMAT*)FpReg82;
  1798. ULONG64 mant = f82->significand;
  1799. if (mant)
  1800. {
  1801. int exp = (f82->exponent ? (f82->exponent - 0xffff) : -0x3ffe) - 63;
  1802. // try to minimize abs(iExp)
  1803. while (exp > 0 && mant && !(mant & (ULONG64(1)<<63)))
  1804. {
  1805. mant <<= 1;
  1806. --exp;
  1807. }
  1808. while (exp < 0 && mant && !(mant & 1))
  1809. {
  1810. mant >>= 1;
  1811. ++exp;
  1812. }
  1813. f = ldexp(double(mant), exp);
  1814. if (f82->sign)
  1815. {
  1816. f = -f;
  1817. }
  1818. }
  1819. return f;
  1820. }
  1821. void
  1822. DoubleToFloat82(double f, FLOAT128* FpReg82)
  1823. {
  1824. ZeroMemory(FpReg82, sizeof(FLOAT128));
  1825. FLOAT82_FORMAT* f82 = (FLOAT82_FORMAT*)FpReg82;
  1826. // Normalize
  1827. int exp;
  1828. f = frexp(f, &exp);
  1829. if (f < 0)
  1830. {
  1831. f82->sign = 1;
  1832. f = -f;
  1833. }
  1834. // shift fraction into integer part
  1835. ULONG64 mant;
  1836. while (double(mant = ULONG64(f)) < f)
  1837. {
  1838. f = f * 2.0;
  1839. --exp;
  1840. }
  1841. f82->exponent = exp + 0xffff + 0x3f;
  1842. f82->significand = mant;
  1843. }