用C ++解析float函数

时间:2014-07-26 13:21:03

标签: c++ performance parsing

我的问题是关于 6502 发布的解决方案 [c++ stringstream is too slow, how to speed up? 他发布的解析Float方法很快,但是它没有给出大的双值的正确结果。

  

输入:

     
    

132.12345645645645

  
     

输出:

     
    

132.123

  
double parseFloat(const std::string& input){
    const char *p = input.c_str();
    if (!*p || *p == '?')
        return NAN_D;
    int s = 1;
    while (*p == ' ') p++;

    if (*p == '-') {
        s = -1; p++;
    }

    double acc = 0;
    while (*p >= '0' && *p <= '9')
        acc = acc * 10 + *p++ - '0';

    if (*p == '.') {
        double k = 0.1;
        p++;
        while (*p >= '0' && *p <= '9') {
            acc += (*p++ - '0') * k;
            k *= 0.1;
        }
    }
    if (*p) die("Invalid numeric format");
    return s * acc;
}

我想知道有没有办法改变这个功能以获得正确的结果。

2 个答案:

答案 0 :(得分:8)

如果您使用cout打印结果,请确保设置必要的精度:

cout.precision(20);

live example

然而,正如您所指出的更简单的方法是:

double string_to_double( const std::string& s )
 {
   std::istringstream i(s);
   double x;
   if (!(i >> x))
     return std::numeric_limits<double>::quiet_NaN(); // Or anything you prefer
   return x;
 }

注意:由于舍入错误,超过数字位数可能不会在最右边的部分产生100%的预期结果。

答案 1 :(得分:1)

小数点后的数字缩放明显比无用的差。

乘以0.1是一个错误 ......尤其是因为0.1没有完全用二进制浮点表示。因此,在循环中循环,重复乘以0.1会累积越来越多的错误。

对于大数字,当将数字乘以10并添加下一个数字值时,您将累积更多错误: - (

诀窍是将数字累加为unsigned long long(假设至少为64位),忽略.但计算其后的位数。当你有所有的数字时,浮动整数然后除以所需的10的幂。现在你最多有一个舍入(浮点数,如果你有超过53位的值)和除法中的第二个。但是,事情会变得复杂......如果你的数字值超过你在unsigned long long中可以容纳的数字,你需要停止添加数字(和圆形)......如果这个数字发生在{{1}之前你需要计算数字,然后乘以10的幂。

NB :一般情况下,十进制到二进制浮点转换为。如果你要转换没有指数的数字,并且位数是合理的,那也不算太糟糕。咬你的问题是如何创建10的大功率乘以/除以,而不会引入(不可接受的)错误。