`
longsy
  • 浏览: 138032 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

C函数源码解读:atof

阅读更多
作用:将一个asii字符串转化为double类型的数据
头文件:stdlib.h

/* Convert a string to a double.  */
double
atof (const char *nptr)
{
  return strtod (nptr, (char **) NULL);
}


#if HAVE_CONFIG_H
# include <config.h>
#endif

#include <errno.h>
#ifndef errno
extern int errno;
#endif

#include <ctype.h>

#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
# define IN_CTYPE_DOMAIN(c) 1
#else
# define IN_CTYPE_DOMAIN(c) isascii(c)
#endif

#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
#define TOLOWER(c) (IN_CTYPE_DOMAIN (c) ? tolower(c) : (c))

#include <math.h>

#include <float.h>
#include <stdlib.h>
#include <string.h>

/* Convert NPTR to a double.  If ENDPTR is not NULL, a pointer to the
   character after the last one used in the number is put in *ENDPTR.  */
double
strtod (const char *nptr, char **endptr)
{
  register const char *s;
  short int sign;

  /* The number so far.  */
  double num;

  int got_dot;                  /* Found a decimal point.  */
  int got_digit;                /* Seen any digits.  */

  /* The exponent of the number.  */
  long int exponent;

  if (nptr == NULL) /*如果为空串,则结束转换*/
    {
      errno = EINVAL;
      goto noconv; /*转向处理无法转换的代码*/
    }

  s = nptr;

  /* Eat whitespace.  */
  while (ISSPACE (*s))
    ++s;

  /* Get the sign.  */
  sign = *s == '-' ? -1 : 1;
  if (*s == '-' || *s == '+')
    ++s;

  num = 0.0;
  got_dot = 0;
  got_digit = 0;
  exponent = 0;
  for (;; ++s)
    {
      if (ISDIGIT (*s))
        {
          got_digit = 1;

          /* Make sure that multiplication by 10 will not overflow.  */
          if (num > DBL_MAX * 0.1)
            /* The value of the digit doesn't matter, since we have already
               gotten as many digits as can be represented in a `double'.
               This doesn't necessarily mean the result will overflow.
               The exponent may reduce it to within range.

               We just need to record that there was another
               digit so that we can multiply by 10 later.  */
            ++exponent;
          else
            num = (num * 10.0) + (*s - '0');

          /* Keep track of the number of digits after the decimal point.
             If we just divided by 10 here, we would lose precision.  */
          if (got_dot)
            --exponent;
        }
      else if (!got_dot && *s == '.')
        /* Record that we have found the decimal point.  */
        got_dot = 1;
      else
        /* Any other character terminates the number.  */
        break;
    }

  if (!got_digit)
    goto noconv;

  if (TOLOWER (*s) == 'e')
    {
      /* Get the exponent specified after the `e' or `E'.  */
      int save = errno;
      char *end;
      long int exp;

      errno = 0;
      ++s;
      exp = strtol (s, &end, 10);
      if (errno == ERANGE)
        {
          /* The exponent overflowed a `long int'.  It is probably a safe
             assumption that an exponent that cannot be represented by
             a `long int' exceeds the limits of a `double'.  */
          if (endptr != NULL)
            *endptr = end;
          if (exp < 0)
            goto underflow;
          else
            goto overflow;
        }
      else if (end == s)
        /* There was no exponent.  Reset END to point to
           the 'e' or 'E', so *ENDPTR will be set there.  */
        end = (char *) s - 1;
      errno = save;
      s = end;
      exponent += exp;
    }

  if (endptr != NULL)
    *endptr = (char *) s;

  if (num == 0.0)
    return 0.0;

  /* Multiply NUM by 10 to the EXPONENT power,
     checking for overflow and underflow.  */

  if (exponent < 0)
    {
      if (num < DBL_MIN * pow (10.0, (double) -exponent))
        goto underflow;
    }
  else if (exponent > 0)
    {
      if (num > DBL_MAX * pow (10.0, (double) -exponent))
        goto overflow;
    }

  num *= pow (10.0, (double) exponent);

  return num * sign;

overflow:
  /* Return an overflow error.  */
  errno = ERANGE;
  return HUGE_VAL * sign;

underflow:
  /* Return an underflow error.  */
  if (endptr != NULL)
    *endptr = (char *) nptr;
  errno = ERANGE;
  return 0.0;

noconv:
  /* There was no number.  */
  if (endptr != NULL)
    *endptr = (char *) nptr;
  return 0.0;
}


分享到:
评论

相关推荐

    C标准库源代码

    ANSI C标准库函数源代码 如strcat,strcpy,memmvoe库函数

    ACM实用函数选.doc

    ACM,函数,c语言 函数名: atof 功 能: 把字符串转换成浮点数 用 法: double atof(const char *nptr); 程序例: #include #include int main(void) { float f; char *str = "12345.67"; f = atof(str); printf...

    C语言函数及相关知识

    C语言函数及相关知识 函数名: abort 功 能: 异常终止一个进程 用 法: void abort(void); 程序例: #include #include &lt;stdlib.h&gt; int main(void) { printf("Calling abort()\n"); abort(); return 0; /* This ...

    atof函数,内置两个实现函数

    atof函数 内置2个实现函数,可以从一个字符串中提取出数字信息并转换成浮点型数据

    atoi和atof函数的区别

    atoi和atof函数的区别及两个函数的功能分别是什么!

    c语言函数集合

    c语言函数集合,isalpha、atol、atof、calloc、malloc等,包括所有C语言的库函数,即查即用

    C语言函数库-第四章(字符串函数)

    里面包含了C语言函数库里面字符串的函数 例如atof等

    类C语言的脚本解析执行(使用C++语言编写)20080625

    本组建主要用于在程序中解析预先编写的类C脚本,并依据脚本执行,可通过调用外部指针函数读入输入变量执行计算,最终得出计算结果写入输出变量中;用户可通过读取输出变量获取最终的结果。 脚本中可调用函数,函数...

    Linux C函数详解

    Linux相关函数说明. 字符测试函数(isblank..),数据转换函数(atoi,atof...)

    linux C函数

    atoi和atof函数的讲解,内涵讲解,库函数说明原理!

    C语言double与字符串互相转换的实现 atof ftoa

    移植功能,如计算器,C语言某些平台中没有C库中函数atof,ftoa,需要自己实现。

    C库函数(字符串转换篇)

    包括的函数: atof 将字符串转换成浮点型数 atoi 将字符串转换成整型数 atol 将字符串转换成长整型数 gcvt 将浮点型数转换为字符串,取四舍五入 strtod 将字符串转换成长整型数 strtol 将字符串转换成长整型数 ...

    C语言常用数字和字符串转换函数

    C语言常用数字和字符串转换函数,toi 字符串转换成整型数 atol 字符串转换成长整型数 atof 字符串转换成浮点型数 strtol 字符串转换成长整型数 strtoul 字符串转换成无符号长整型数 strtod 字符串转换成浮点数

    明解C语言(第3版)入门篇.[日]柴田望洋(带详细书签).pdf 【半高清】

    atoi函数、atol函数、atof函数:转换字符串 333 总结 336 第12章 结构体 339 12-1 结构体 340 数据关联性 340 结构体 342 结构体成员和运算符 344 成员的初始化 345 结构体成员和-&gt;运算符 346 结构体和...

    c语言字符串_数字转换函数大全

    atof(将字符串转换成浮点型数) atoi(将字符串转换成整型数) atol(将字符串转换成长整型数) strtod(将字符串转换成浮点数) strtol(将字符串转换成长整型数) strtoul(将字符串转换成无符号长整型数) toascii(将整型数...

    字符串处理函数

    字符串是Auto Lisp的基本数据之一,它常用于磁盘文件名,标识符的打印名等。Auto Lisp语言和其它高级语言一样,提供了一些字符串进行处理的系统... ·ATOF ·RTOS ·ANGTOS ·STRCAT ·SUBSTR ·STRCASE ·READ

    Python Console Library Project:控制台功能-开源

    Python的控制台功能简编(类似于BC conio.h)实际上:atof(s):btoi(ch):btos(ch):charfilter(ch):clrscr(n = 150):cmp(a,b): finput(b =“”):getarrow():getch():gotoxy(x = 0,y = 0...

    c语言标准库中字符转换函数和数字转换函数

    atof();将字符转化为浮点型 例:char ch3;float f=atof(ch3); strtod(); 将字符串转化为双精度类型 例:string str1;double d=strtod(str1); strtol(); 将字符串转化为长整型 例:string str2; long int li=...

    -C++参考大全(第四版) (2010 年度畅销榜

    30.5 atof函数 30.6 atoi函数 30.7 atol函数 30.8 bsearch函数 30.9 div函数 30.10 exit函数 30.11 getenv函数 30.12 labs函数 30.13 ldiv函数 30.14 longjmp函数 30.15 mblen函数 30.16 mbstowes函数 30.17 mbtowc...

    C语言讲义.doc

    1.10.4 -c编译 16 1.10.5 链接 16 1.11 操作系统结构 17 1.11.1 用户模式 17 1.11.2 内核模式 17 1.12 64位,32位系统区别 18 1.12.1 CPU内部结构与寄存器 18 1.12.2 RISC与CISC CPU构架 18 1.12.3 SPARC,x86与ARM ...

Global site tag (gtag.js) - Google Analytics