如何仅使用math.h将字符串转换为double

时间:2011-02-17 11:52:06

标签: c++ c string floating-point

我正在尝试将字符串转换为double,但由于我正在使用Windows本机应用程序(如仅链接到ntdll.dll),因此我没有大多数标准库可用。我可以在math.h中使用基本的FP支持,但基本上就是它。

如何将字符串转换为最接近该字符串中表示的有理数的双精度?

3 个答案:

答案 0 :(得分:5)

如果你真的想要得到最近的,问题就很难了,你需要任意精度算术来实现这个结果。例如,请参阅ftp://ftp.ccs.neu.edu/pub/people/will/howtoread.ps

答案 1 :(得分:2)

你见过Open NT Native Template Library,尤其是STLx部分吗?基本上,你可以在Native或Kernel代码中获得接近普通C ++运行时的东西。

答案 2 :(得分:1)

假设JSON grammar(当前链接,Google cached version here)可以接受,以下内容或多或少直接来自内部开发的JSON解析代码,是其语法图的文字实现:

/*

    defined functions for handling the input:

        nextChar() - peeks at the next character of input

        getAndRemoveCharacter() - returns the next character of input and
        dequeues it

    This code also assumes you have BOOL, YES and NO defined; I've left this in
    for clarity
*/

double getNumber()
{
    // determine whether the number is negative - it'll start with a '-' if so
    BOOL negative = NO;
    if(nextChar() == '-')
    {
        negative = YES;
        getAndRemoveCharacter();
    }

    // seed the output number to 0
    double number = 0.0;

    // if the next character isn't a '0' then this is the number proper, so
    // just pull off the digits and assemble the number; otherwise this number
    // is either 0 itself (in which case the initial seed is correct) or a
    // decimal starting in 0
    if(nextChar() != '0')
    {
        while(nextChar() >= '0' && nextChar() <= '9')
        {
            number *= 10.0;
            number += getAndRemoveCharacter() - '0';
        }
    }
    else
        getAndRemoveCharacter();

    // if this is a decimal then jump on to the decimal part and deserialise
    // digits, much as above
    if(nextChar() == '.')
    {
        getAndRemoveCharacter();
        double decimalMultiplier = 1.0;
        while(nextChar() >= '0' && nextChar() <= '9')
        {
            decimalMultiplier /= 10.0;
            number += (double)(getAndRemoveCharacter() - '0') * decimalMultiplier;
        }
    }

    // if this number has an exponent then deal with that
    if(nextChar() == 'e' || nextChar() == 'E')
    {
        getAndRemoveCharacter();

        double exponent = 0.0;
        BOOL exponentPositive = YES;

        // JSON allows positive exponents to start with + (unlike
        // the mantissa) and requires negative exponents to start with -
        if(nextChar() == '+')
        {
            getAndRemoveCharacter();
        }
        else
            if(nextChar() == '-')
            {
                exponentPositive = NO;
                getAndRemoveCharacter();
            }

        // read out digits and assemble exponent
        while(nextChar() >= '0' && nextChar() <= '9')
        {
            exponent *= 10.0;
            exponent += getAndRemoveCharacter() - '0';
        }

        // apply exponent
        number *= pow(10.0, exponentPositive ? exponent : -exponent);
    }

    // negate if necessary and return
    return negative ? -number : number;
}

任何将ASCII字母置于普通ASCII范围内的字符类型都可以使用,因此它应该在ASCII和变量以及unicode上同样有效。我猜你可能想直接把一个字符串作为一个参数,而不是把所有这些调用都拿出来;它们是原始的,因为输入流来自远方,所以它们可能会阻塞。

'pow'中使用的唯一math.h函数,其他一切都只是原始操作。