home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 1.ddi / MATHSRC.ZIP / STRTOD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  4.9 KB  |  153 lines

  1. /*------------------------------------------------------------------------
  2.  * filename - strtod.c
  3.  *
  4.  * function(s)
  5.  *        strtod   - converts string to a double value
  6.  *        _strtold - converts string to a long double value
  7.  *        Get      - gets a character from a string
  8.  *        UnGet    - ungets a character from a string
  9.  *-----------------------------------------------------------------------*/
  10.  
  11. /*
  12.  *      C/C++ Run Time Library - Version 5.0
  13.  *
  14.  *      Copyright (c) 1987, 1992 by Borland International
  15.  *      All Rights Reserved.
  16.  *
  17.  */
  18.  
  19.  
  20. #include <errno.h>
  21. #include <_scanf.h>
  22. #include <stddef.h>
  23.  
  24. #include <_math.h>
  25. #include <stdlib.h>
  26. #include <math.h>
  27. #include <float.h>
  28.  
  29. /*
  30.   Internal RTL function to perform double/float truncations.
  31. */
  32. #define FLT     0
  33. #define DBL     1
  34. double near pascal __ldtrunc(int flag, long double x, double xhuge);
  35.  
  36.  
  37. /*---------------------------------------------------------------------*
  38.  
  39. Name            Get - gets a character from a string
  40.  
  41. Usage           int Get (char **strPP)
  42.  
  43. Description     returns the next character in a string
  44.  
  45. Return value    the next character in a string.  if that character is
  46.                 the null character, Get returns -1.
  47.  
  48. *---------------------------------------------------------------------*/
  49. static  int  near  Get (char **strPP)
  50. {
  51. register    unsigned    c;
  52.  
  53.     return  ((c = *((*strPP) ++)) == 0) ? -1 : c;
  54. }
  55.  
  56.  
  57. /*---------------------------------------------------------------------*
  58.  
  59. Name            UnGet - ungets a character from a string
  60.  
  61. Usage           void UnGet (char c, char **strPP)
  62.  
  63. Description     decrements a string pointer
  64.  
  65. Return value    Nothing
  66.  
  67. *---------------------------------------------------------------------*/
  68. static  void  near  UnGet (char c, char **strPP)
  69. {
  70.     --(*strPP);         /* ignore c, we don't allow the string to change */
  71. #pragma warn -par
  72. }
  73. #pragma warn .par
  74.  
  75.  
  76. /*--------------------------------------------------------------------------*
  77.  
  78. Name            strtod   - converts string to a double value
  79.                 _strtold - converts string to a long double value
  80.  
  81. Usage           double strtod(const char *strP, char **suffixPP);
  82.                 long double _strtold(const char *strP, char **suffixPP);
  83.  
  84. Prototype in    stdlib.h
  85.  
  86. Description     Convert a string to a double precision or long double real.
  87.                 The syntax of the string must be:
  88.  
  89.                 float    ::= [isspace]* [sign] [realnum] [exponent]
  90.  
  91.                 isspace  ::= as per <ctype.h>:isspace
  92.  
  93.                 realnum  ::= {digit [digit]* ['.' [digit]* ]} |
  94.                              {'.' digit [digit]*}
  95.  
  96.                 exponent ::= 'e'|'E' [sign] digit [digit]*
  97.  
  98.                 "strP" is a pointer to the ASCII string to be scanned.
  99.  
  100.                 "suffixPP" is a pointer to  a string pointer to be updated.
  101.                 If it is not NULL then (*suffixPP) will be updated to point
  102.                 to the first character following  the section of the string
  103.                 which was consumed.
  104.  
  105.                 The digits must be decimal.
  106.  
  107. Return value    strtod and _strtold return the converted value of the input
  108.                 string as a double or long double value, respectively.
  109.                 If the source string is  not a valid floating point numeral
  110.                 then the  result value is  zero and the  next char pointer
  111.                 will equal  the starting string  pointer. If the  number is
  112.                 too large or too tiny then the result is signed HUGE_VAL
  113.                 (strtod), _LHUGE_VAL (_strtold), or zero, and errno is
  114.                 set to ERANGE.
  115.  
  116. *--------------------------------------------------------------------------*/
  117.  
  118. long double  _strtold (const char *strP, char **suffixPP)
  119. {
  120.                 int     charCt = 0;
  121.                 int     status;
  122.                 long double  result;
  123.  
  124.                 result = _scantod (
  125.                                                 (int near (*) (void *))Get,
  126.                                                 (void near (*) (int ch, void *))UnGet,
  127.                                                 &strP,
  128.                                                 0x7FFF,
  129.                                                 &charCt,
  130.                                                 &status
  131.                                                 );
  132.  
  133.                 if (status <= 0)
  134.                                 strP -= charCt;
  135.                 else if (status == 2)
  136.                                 errno = ERANGE;
  137.  
  138.                 if (suffixPP != NULL)
  139.                                 *suffixPP = (char *)strP;
  140.  
  141.                 return (result);
  142. }
  143.  
  144. double  strtod (const char *strP, char **suffixPP)
  145. {
  146.         /*
  147.           __ldtrunc sets 'errno' to ERANGE if the result
  148.           is to become 0 or HUGE_VAL.
  149.         */
  150.         return __ldtrunc(DBL, _strtold(strP, suffixPP), HUGE_VAL);
  151. }
  152.  
  153.