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.

124 lines
4.2 KiB

  1. /***
  2. *strtod.c - convert string to floating point number
  3. *
  4. * Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Convert character string to floating point number
  8. *
  9. *Revision History:
  10. * 09-09-83 RKW Module created
  11. * 08-19-85 TDC changed to strtod
  12. * 04-13-87 JCR Added "const" to declaration
  13. * 04-20-87 BCM Added checks for negative overflow and for underflow
  14. * 11-09-87 BCM different interface under ifdef MTHREAD
  15. * 12-11-87 JCR Added "_LOAD_DS" to declaration
  16. * 02-22-88 JCR Added cast to nptr to get rid of cl const warning
  17. * 05-24-88 PHG Merged DLL and normal versions
  18. * 08-24-88 PHG No digits found => *endptr = nptr [ANSI]
  19. * Revised test order so invalid detection works always
  20. * 10-20-88 JCR Changed 'DOUBLE' to 'double' for 386
  21. * 11-20-89 JCR atof() is always _cdecl in 386 (not pascal)
  22. * 03-05-90 GJF Fixed calling type, added #include <cruntime.h>,
  23. * removed #include <register.h>, removed redundant
  24. * prototypes, removed some leftover 16-bit support and
  25. * fixed the copyright. Also, cleaned up the formatting
  26. * a bit.
  27. * 07-23-90 SBM Compiles cleanly with -W3 (added/removed appropriate
  28. * #includes)
  29. * 08-01-90 SBM Renamed <struct.h> to <fltintrn.h>
  30. * 09-27-90 GJF New-style function declarators.
  31. * 10-21-92 GJF Made char-to-int conversion unsigned.
  32. * 04-06-93 SKS Replace _CRTAPI* with _cdecl
  33. * 09-06-94 CFW Replace MTHREAD with _MT.
  34. * 12-15-98 GJF Changes for 64-bit size_t.
  35. *
  36. *******************************************************************************/
  37. #include <cruntime.h>
  38. #include <stdlib.h>
  39. #include <fltintrn.h>
  40. #include <string.h>
  41. #include <ctype.h>
  42. #include <errno.h>
  43. #include <math.h>
  44. /***
  45. *double strtod(nptr, endptr) - convert string to double
  46. *
  47. *Purpose:
  48. * strtod recognizes an optional string of tabs and spaces,
  49. * then an optional sign, then a string of digits optionally
  50. * containing a decimal point, then an optional e or E followed
  51. * by an optionally signed integer, and converts all this to
  52. * to a floating point number. The first unrecognized
  53. * character ends the string, and is pointed to by endptr.
  54. *
  55. *Entry:
  56. * nptr - pointer to string to convert
  57. *
  58. *Exit:
  59. * returns value of character string
  60. * char **endptr - if not NULL, points to character which stopped
  61. * the scan
  62. *
  63. *Exceptions:
  64. *
  65. *******************************************************************************/
  66. double __cdecl strtod (
  67. const char *nptr,
  68. REG2 char **endptr
  69. )
  70. {
  71. #ifdef _MT
  72. struct _flt answerstruct;
  73. #endif
  74. FLT answer;
  75. double tmp;
  76. unsigned int flags;
  77. REG1 char *ptr = (char *) nptr;
  78. /* scan past leading space/tab characters */
  79. while ( isspace((int)(unsigned char)*ptr) )
  80. ptr++;
  81. /* let _fltin routine do the rest of the work */
  82. #ifdef _MT
  83. /* ok to take address of stack variable here; fltin2 knows to use ss */
  84. answer = _fltin2( &answerstruct, ptr, (int)strlen(ptr), 0, 0);
  85. #else
  86. answer = _fltin(ptr, (int)strlen(ptr), 0, 0);
  87. #endif
  88. if ( endptr != NULL )
  89. *endptr = (char *) ptr + answer->nbytes;
  90. flags = answer->flags;
  91. if ( flags & (512 | 64)) {
  92. /* no digits found or invalid format:
  93. ANSI says return 0.0, and *endptr = nptr */
  94. tmp = 0.0;
  95. if ( endptr != NULL )
  96. *endptr = (char *) nptr;
  97. }
  98. else if ( flags & (128 | 1) ) {
  99. if ( *ptr == '-' )
  100. tmp = -HUGE_VAL; /* negative overflow */
  101. else
  102. tmp = HUGE_VAL; /* positive overflow */
  103. errno = ERANGE;
  104. }
  105. else if ( flags & 256 ) {
  106. tmp = 0.0; /* underflow */
  107. errno = ERANGE;
  108. }
  109. else
  110. tmp = answer->dval;
  111. return(tmp);
  112. }