Source code of Windows XP (NT5)
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.

133 lines
2.8 KiB

  1. /***
  2. *cfout.c - Encode interface for C
  3. *
  4. * Copyright (c) 1991-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *
  8. *Revision History:
  9. * 07-20-91 GDP Ported to C from assembly
  10. * 04-30-92 GDP Added _dtold routine (moved here from ldtod.c)
  11. * 05-14-92 GDP NDIGITS is now 17 (instead of 16)
  12. * 06-18-92 GDP Use double instead of DOUBLE to remove C8 warning
  13. * 04-06-93 SKS Replace _CALLTYPE* with __cdecl
  14. * 09-06-94 CFW Replace MTHREAD with _MT.
  15. * 09-05-00 GB Changed the defination of fltout functions. Use DOUBLE
  16. * instead of double
  17. *
  18. *******************************************************************************/
  19. #include <string.h>
  20. #include <cv.h>
  21. #define NDIGITS 17
  22. void __dtold(_LDOUBLE *pld, double *px);
  23. #ifndef _MT
  24. static struct _strflt ret;
  25. static FOS fos;
  26. #endif
  27. #ifdef _MT
  28. STRFLT __cdecl _fltout2(DOUBLE x, STRFLT flt, char *resultstr)
  29. {
  30. _LDOUBLE ld;
  31. FOS autofos;
  32. __dtold(&ld, (double *)&x);
  33. flt->flag = $I10_OUTPUT(ld,NDIGITS,0,&autofos);
  34. flt->sign = autofos.sign;
  35. flt->decpt = autofos.exp;
  36. strcpy(resultstr,autofos.man);
  37. flt->mantissa = resultstr;
  38. return flt;
  39. }
  40. #else
  41. STRFLT __cdecl _fltout(DOUBLE x)
  42. {
  43. _LDOUBLE ld;
  44. __dtold(&ld, (double *)&x);
  45. ret.flag = $I10_OUTPUT(ld,NDIGITS,0,&fos);
  46. ret.sign = fos.sign;
  47. ret.decpt = fos.exp;
  48. ret.mantissa = fos.man;
  49. return &ret;
  50. }
  51. #endif
  52. /***
  53. * __dtold - convert a double into a _LDOUBLE
  54. *
  55. *Purpose: Use together with i10_output() to get string conversion
  56. * for double
  57. *
  58. *Entry: double *px
  59. *
  60. *Exit: the corresponding _LDOUBLE value is returned in *pld
  61. *
  62. *Exceptions:
  63. *
  64. *******************************************************************************/
  65. void __dtold(_LDOUBLE *pld, double *px)
  66. {
  67. u_short exp;
  68. u_short sign;
  69. u_long manhi, manlo;
  70. u_long msb = MSB_ULONG;
  71. u_short ldexp = 0;
  72. exp = (*U_SHORT4_D(px) & (u_short)0x7ff0) >> 4;
  73. sign = *U_SHORT4_D(px) & (u_short)0x8000;
  74. manhi = *UL_HI_D(px) & 0xfffff;
  75. manlo = *UL_LO_D(px);
  76. switch (exp) {
  77. case D_MAXEXP:
  78. ldexp = LD_MAXEXP;
  79. break;
  80. case 0:
  81. /* check for zero */
  82. if (manhi == 0 && manlo == 0) {
  83. *UL_MANHI_LD(pld) = 0;
  84. *UL_MANLO_LD(pld) = 0;
  85. *U_EXP_LD(pld) = 0;
  86. return;
  87. }
  88. /* we have a denormal -- we'll normalize later */
  89. ldexp = (u_short) ((s_short)exp - D_BIAS + LD_BIAS + 1);
  90. msb = 0;
  91. break;
  92. default:
  93. exp -= D_BIAS;
  94. ldexp = (u_short) ((s_short)exp + LD_BIAS);
  95. break;
  96. }
  97. *UL_MANHI_LD(pld) = msb | manhi << 11 | manlo >> 21;
  98. *UL_MANLO_LD(pld) = manlo << 11;
  99. /* normalize if necessary */
  100. while ((*UL_MANHI_LD(pld) & MSB_ULONG) == 0) {
  101. /* shift left */
  102. *UL_MANHI_LD(pld) = *UL_MANHI_LD(pld) << 1 |
  103. (MSB_ULONG & *UL_MANLO_LD(pld) ? 1: 0);
  104. (*UL_MANLO_LD(pld)) <<= 1;
  105. ldexp --;
  106. }
  107. *U_EXP_LD(pld) = sign | ldexp;
  108. }