我要的是atof()函数的算法过程。
谁能帮忙提供一些相关的信息?谢谢了。

解决方案 »

  1.   

    /* 
     * strtod.c --
     *
     * Source code for the "strtod" library procedure.
     *
     * Copyright (c) 1988-1993 The Regents of the University of California.
     * Copyright (c) 1994 Sun Microsystems, Inc.
     *
     * See the file "license.terms" for information on usage and redistribution
     * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
     *
     * RCS: @(#) $Id: strtod.c,v 1.6 2002/02/25 14:26:12 dgp Exp $
     */#include "tclInt.h"
    #include "tclPort.h"
    #include <ctype.h>#ifndef TRUE
    #define TRUE 1
    #define FALSE 0
    #endif
    #ifndef NULL
    #define NULL 0
    #endifstatic int maxExponent = 511; /* Largest possible base 10 exponent.  Any
     * exponent larger than this will already
     * produce underflow or overflow, so there's
     * no need to worry about additional digits.
     */
    static double powersOf10[] = { /* Table giving binary powers of 10.  Entry */
        10., /* is 10^2^i.  Used to convert decimal */
        100., /* exponents into floating-point numbers. */
        1.0e4,
        1.0e8,
        1.0e16,
        1.0e32,
        1.0e64,
        1.0e128,
        1.0e256
    };
     
    /*
     *----------------------------------------------------------------------
     *
     * strtod --
     *
     * This procedure converts a floating-point number from an ASCII
     * decimal representation to internal double-precision format.
     *
     * Results:
     * The return value is the double-precision floating-point
     * representation of the characters in string.  If endPtr isn't
     * NULL, then *endPtr is filled in with the address of the
     * next character after the last one that was part of the
     * floating-point number.
     *
     * Side effects:
     * None.
     *
     *----------------------------------------------------------------------
     */double
    strtod(string, endPtr)
        CONST char *string; /* A decimal ASCII floating-point number,
     * optionally preceded by white space.
     * Must have form "-I.FE-X", where I is the
     * integer part of the mantissa, F is the
     * fractional part of the mantissa, and X
     * is the exponent.  Either of the signs
     * may be "+", "-", or omitted.  Either I
     * or F may be omitted, or both.  The decimal
     * point isn't necessary unless F is present.
     * The "E" may actually be an "e".  E and X
     * may both be omitted (but not just one).
     */
        char **endPtr; /* If non-NULL, store terminating character's
     * address here. */
    {
        int sign, expSign = FALSE;
        double fraction, dblExp, *d;
        register CONST char *p;
        register int c;
        int exp = 0; /* Exponent read from "EX" field. */
        int fracExp = 0; /* Exponent that derives from the fractional
     * part.  Under normal circumstatnces, it is
     * the negative of the number of digits in F.
     * However, if I is very long, the last digits
     * of I get dropped (otherwise a long I with a
     * large negative exponent could cause an
     * unnecessary overflow on I alone).  In this
     * case, fracExp is incremented one for each
     * dropped digit. */
        int mantSize; /* Number of digits in mantissa. */
        int decPt; /* Number of mantissa digits BEFORE decimal
     * point. */
        CONST char *pExp; /* Temporarily holds location of exponent
     * in string. */    /*
         * Strip off leading blanks and check for a sign.
         */    p = string;
        while (isspace(UCHAR(*p))) {
    p += 1;
        }
        if (*p == '-') {
    sign = TRUE;
    p += 1;
        } else {
    if (*p == '+') {
        p += 1;
    }
    sign = FALSE;
        }    /*
         * Count the number of digits in the mantissa (including the decimal
         * point), and also locate the decimal point.
         */    decPt = -1;
        for (mantSize = 0; ; mantSize += 1)
        {
    c = *p;
    if (!isdigit(c)) {
        if ((c != '.') || (decPt >= 0)) {
    break;
        }
        decPt = mantSize;
    }
    p += 1;
        }    /*
         * Now suck up the digits in the mantissa.  Use two integers to
         * collect 9 digits each (this is faster than using floating-point).
         * If the mantissa has more than 18 digits, ignore the extras, since
         * they can't affect the value anyway.
         */
        
        pExp  = p;
        p -= mantSize;
        if (decPt < 0) {
    decPt = mantSize;
        } else {
    mantSize -= 1; /* One of the digits was the point. */
        }
        if (mantSize > 18) {
    fracExp = decPt - 18;
    mantSize = 18;
        } else {
    fracExp = decPt - mantSize;
        }
        if (mantSize == 0) {
    fraction = 0.0;
    p = string;
    goto done;
        } else {
    int frac1, frac2;
    frac1 = 0;
    for ( ; mantSize > 9; mantSize -= 1)
    {
        c = *p;
        p += 1;
        if (c == '.') {
    c = *p;
    p += 1;
        }
        frac1 = 10*frac1 + (c - '0');
    }
    frac2 = 0;
    for (; mantSize > 0; mantSize -= 1)
    {
        c = *p;
        p += 1;
        if (c == '.') {
    c = *p;
    p += 1;
        }
        frac2 = 10*frac2 + (c - '0');
    }
    fraction = (1.0e9 * frac1) + frac2;
        }    /*
         * Skim off the exponent.
         */    p = pExp;
        if ((*p == 'E') || (*p == 'e')) {
    p += 1;
    if (*p == '-') {
        expSign = TRUE;
        p += 1;
    } else {
        if (*p == '+') {
    p += 1;
        }
        expSign = FALSE;
    }
    if (!isdigit(UCHAR(*p))) {
        p = pExp;
        goto done;
    }
    while (isdigit(UCHAR(*p))) {
        exp = exp * 10 + (*p - '0');
        p += 1;
    }
        }
        if (expSign) {
    exp = fracExp - exp;
        } else {
    exp = fracExp + exp;
        }    /*
         * Generate a floating-point number that represents the exponent.
         * Do this by processing the exponent one bit at a time to combine
         * many powers of 2 of 10. Then combine the exponent with the
         * fraction.
         */
        
        if (exp < 0) {
    expSign = TRUE;
    exp = -exp;
        } else {
    expSign = FALSE;
        }
        if (exp > maxExponent) {
    exp = maxExponent;
    errno = ERANGE;
        }
        dblExp = 1.0;
        for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
    if (exp & 01) {
        dblExp *= *d;
    }
        }
        if (expSign) {
    fraction /= dblExp;
        } else {
    fraction *= dblExp;
        }done:
        if (endPtr != NULL) {
    *endPtr = (char *) p;
        }    if (sign) {
    return -fraction;
        }
        return fraction;
    }
      

  2.   

    strtod,也是把字符串转换为浮点数。
    http://tcl.apache.org/sources/tcl/compat/strtod.c.html
      

  3.   

    羽战士
    if (!isdigit(UCHAR(*p))) 这句看的不是太懂。
    你能帮忙解释一下吗?
      

  4.   

    我曾经也遇到过这个问题,后来自己写了一个CString2Int的函数,应该对楼主有所帮助.
    字符串str="123"其实就相当于是一个数组char str[4],其中str[0]='1',str[1]='2',str[2]='3',str[3]='\0',在CString中,可以用GetAt取到每个字符的Ascii码,可以从后向前取,这样第1次就是个位,即10^0,第2次就是10^1,以此类推,再将Ascii转化位int就可以了,如果还不懂就留下个email,我发给你代码