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.

129 lines
3.5 KiB

  1. /***
  2. *gcvt.c - convert floating point number to character string
  3. *
  4. * Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Converts floating point number into character string representation.
  8. *
  9. *Revision History:
  10. * 09-09-93 RKW written
  11. * 11-09-87 BCM different interface under ifdef MTHREAD
  12. * 12-11-87 JCR Added "_LOAD_DS" to declaration
  13. * 05-24-88 PHG Merged DLL and normal versions
  14. * 10-20-88 JCR Changed 'DOUBLE' to 'double' for 386
  15. * 06-27-89 PHG Changed "ndec" to "ndec-1" to correct significant
  16. * digits in exponential format (C6 bug #2124)
  17. * 03-05-90 GJF Fixed calling type, added #include <cruntime.h>,
  18. * removed #include <register.h>, removed redundant
  19. * prototypes, removed some leftover 16-bit support and
  20. * fixed the copyright. Also, cleaned up the formatting
  21. * a bit.
  22. * 07-20-90 SBM Compiles cleanly with -W3 (added/removed appropriate
  23. * #includes)
  24. * 08-01-90 SBM Renamed <struct.h> to <fltintrn.h>
  25. * 09-27-90 GJF New-style function declarators.
  26. * 01-21-91 GJF ANSI naming.
  27. * 08-13-92 SKS An old bug that was fixed in C 6.0 but that did not
  28. * make it into C 7.0, an off by 1 error when switching
  29. * from fixed point to scientific notation
  30. * 04-06-93 SKS Replace _CRTAPI* with _cdecl
  31. * 09-06-94 CFW Replace MTHREAD with _MT.
  32. * 12-21-95 JWM Replaced '.' with *__decimal_point; includes nlsint.h.
  33. * 09-05-00 GB Changed the defination of fltout functions. Use DOUBLE
  34. * instead of double
  35. *
  36. *******************************************************************************/
  37. #include <cruntime.h>
  38. #include <fltintrn.h>
  39. #include <internal.h>
  40. #include <nlsint.h>
  41. /***
  42. *double _gcvt(value, ndec, buffer) - convert floating point value to char
  43. * string
  44. *
  45. *Purpose:
  46. * _gcvt converts the value to a null terminated ASCII string
  47. * buf. It attempts to produce ndigit significant digits
  48. * in Fortran F format if possible, ortherwise E format,
  49. * ready for printing. Trailing zeros may be suppressed.
  50. * No error checking or overflow protection is provided.
  51. * NOTE - to avoid the possibility of generating floating
  52. * point instructions in this code we fool the compiler
  53. * about the type of the 'value' parameter using a struct.
  54. * This is OK since all we do is pass it off as a
  55. * parameter.
  56. *
  57. *Entry:
  58. * value - double - number to be converted
  59. * ndec - int - number of significant digits
  60. * buf - char * - buffer to place result
  61. *
  62. *Exit:
  63. * result is written into buffer; it will be overwritten if it has
  64. * not been made big enough.
  65. *
  66. *Exceptions:
  67. *
  68. *******************************************************************************/
  69. char * __cdecl _gcvt (
  70. double value,
  71. int ndec,
  72. char *buf
  73. )
  74. {
  75. #ifdef _MT
  76. struct _strflt strfltstruct; /* temporary buffers */
  77. char resultstring[21];
  78. #endif
  79. STRFLT string;
  80. int magnitude;
  81. char *rc;
  82. DOUBLE *pdvalue = (DOUBLE *)&value;
  83. REG1 char *str;
  84. REG2 char *stop;
  85. /* get the magnitude of the number */
  86. #ifdef _MT
  87. string = _fltout2( *pdvalue, &strfltstruct, resultstring );
  88. #else
  89. string = _fltout( *pdvalue );
  90. #endif
  91. magnitude = string->decpt - 1;
  92. /* output the result according to the Fortran G format as outlined in
  93. Fortran language specification */
  94. if ( magnitude < -1 || magnitude > ndec-1 )
  95. /* then Ew.d d = ndec */
  96. rc = str = _cftoe( &value, buf, ndec-1, 0);
  97. else
  98. /* Fw.d where d = ndec-string->decpt */
  99. rc = str = _cftof( &value, buf, ndec-string->decpt );
  100. while (*str && *str != *__decimal_point)
  101. str++;
  102. if (*str++) {
  103. while (*str && *str != 'e')
  104. str++;
  105. stop = str--;
  106. while (*str == '0')
  107. str--;
  108. while (*++str = *stop++)
  109. ;
  110. }
  111. return(rc);
  112. }