strtod.c 2.41 KB
/*
=============================================================================
        Copyright (C) 1997-1999 NINTENDO Co.,Ltd.
        
        $RCSfile: strtod.c,v $
        $Revision: 1.1.1.1 $
        $Date: 2002/10/30 02:07:09 $
=============================================================================
関数名:strtod
-----------------------------------------------------------------------------
書式:  #include <string.h>
        double strtod(const char *string, char **endptr)
引数:  string 変換する文字列
        endptr 認識不能文字列へのポインタ格納先
戻り値:文字列 string を double 型に変換した値。
説明:  文字列 string を double 型に変換する。

        文字列 stringは、次の形式で指定する。

        [whitespace][{sign}][digits][.digits][{e | E}[sign]digits]

            <whitespace>    空白類文字 (isspace 参照)
            <sign>          +か−
            <digits>        1桁以上の10進文字列

        10進数値の後には、e、Eに続く指数部をつけられる。
        数字の一部として認識出来ない文字が現れたところで変換を打ち切る。

        endptr が NULL で無いとき、変換を打ち切った文字列へのポインタを
        *endptr にセットする。
-----------------------------------------------------------------------------
*/
#include    "string.h"
#include    "math.h"
#include    "ctype.h"

double strtod(const char *string, char **endptr)
{
    double a = 1.0, b = 0.0,  c = 0, d;

    while(isspace(*string))
      string++;

    if (!*string)   return  0.0;
    if (*string == '+') string++;
    if (*string == '-') {string++; a = -1.0;}

    c = 0;
    while(*string)  {
        if (*string == '.') {
            if (b)  break;
            b = 10.0;
            string++;
        }   else    {
            if (!isdigit(*string))  break;
            if (b)  d = (*string++ - '0') / b;
            else    d = (*string++) - '0';

            if (c > (DBL_MAX-d)/10) return  DBL_MAX;

            if (b)  b *= 10.0;
            else    c *= 10.0;
            c += d;
        }
    }
    c *= a;

    if (*string == 'E' || *string == 'e')    {
        string++;
        a = b = 0;
        if (*string == '+') string++;
        if (*string == '-') {string++; a = 1.0;}

        while(*string)  {
            if (!isdigit(*string))  break;
            b *= 10;
            b += (*string++) - '0';
        }
        b = pow(10, b);
        if (a)  c /= b;
        else    c *= b;
    }

    if (endptr != NULL) *endptr = (char *)string;
    return  c;
}