将浮点(double)转换为字符串

时间:2011-06-30 19:51:29

标签: c++ boost

我遇到了一些我以前从未见过的东西,非常想了解发生了什么。我试图将一个双精度数转换为2位小数并将该值转换为字符串。在完成演员表演后,我发疯了。

以下是代码:

void formatPercent(std::string& percent, const std::string& value, Config& config)
{
    double number = boost::lexical_cast<double>(value);
    if (config.total == 0)
    {
        std::ostringstream err;
        err << "Cannot calculate percent from zero total.";
        throw std::runtime_error(err.str());
    }
    number = (number/config.total)*100;
    // Format the string to only return 2 decimals of precision
    number = floor(number*100 + .5)/100;
    percent = boost::lexical_cast<std::string>(number);

    return;
}

我没有达到我的预期,所以我做了一些调查。我做了以下事情:

std::cout << std::setprecision(10) << "number = " << number << std::endl;
std::cout << "percent = " << percent << std::endl;

...并获得以下内容:

number = 30.63
percent = 30.629999999999999

我怀疑提升正在做一些有趣的事情。有没有人在这里有任何见解?

说真的,这有多奇怪?!?我要求双倍的10位精度并获得4位数。我要求将这4个数字转换成一个字符串并弄得一团糟。发生了什么事?

4 个答案:

答案 0 :(得分:3)

十进制数30.63无法存储在double类型的对象中。最接近的有效double值(实际存储的值)为8621578536647393 * 2^-48,在十进制表示法中为30.629999999999999005240169935859739780426025390625

如果你std::cout << std::setprecision(100) << "number = " << number << std::endl;

,你可以看到

答案 1 :(得分:1)

std :: precision设置要显示的最大有效位数

  

在默认浮点上   符号,精度字段   指定的最大数量   有意义的数字总计显示   计算那些之前和那些   小数点后。请注意   它不是最低限度,因此它   不填充显示的数字   如果数字可以是尾随零   显示的数字少于   精度。

30.629999999999999是30.63

的实际浮点表示

答案 2 :(得分:1)

你要求十位数的精度,但实际的“不准确度”会进一步下降,所以当它被舍入到十位数时,它变得整齐30.63。你的lexical_cast会考虑所有的数字,因此产生精确的浮点值(可能不是你想要的那种精度,但它是计算机内存中最精确的表示形式)。

答案 3 :(得分:0)

问题是浮点数不能准确表示任意十进制值。您所看到的是浮点错误。 Boost准确显示您提供给它的价值。