处理浮子的不准确性

Handle inaccurracy of float

提问人:lalelu 提问时间:6/22/2015 最后编辑:phuclvlalelu 更新时间:1/12/2020 访问量:139

问:

我有一根绳子

strValue = "11.900000"

我想将其解析为浮点值。所以我试了一下:

float fValue = -1;
sscanf_s(strValue.c_str(), "%f", &fValue);

try
{
    double test = std::stod(strValue, &sz);
    fValue = (float) std::stod(strValue, &sz);
}
catch (...)
{
    fValue = -1;
}

因为它是准确的:double

test = 11.900000000000000

因为它是不准确的:float

fValue = 11.8999996

是否有可能准确地做到这一点?(我知道在使用浮点数时存在不准确之处,但有没有更好的方法?

C++ 精度浮点转换

评论

4赞 Phylogenesis 6/22/2015
不。无法将 11.9 表示为 ,如示例所示。基础值是基于二进制的,0.1 的(大多数)倍数在二进制中没有确切的表示。float
0赞 Panagiotis Kanavos 6/22/2015
浮点数不准确,并且存在缩放误差。你的编译器可能支持某个类型,但 C++ 仍然没有标准化的十进制支持 - 它被安排在 C++17 上。decimal
0赞 Panagiotis Kanavos 6/22/2015
在将小数添加到 C++ 之前,您可以使用 Boost MultiPrecision
0赞 David Schwartz 6/22/2015
很难理解你在问什么,因为不清楚你到底想做什么。您显然找到了一种更准确的方法,使用 .那么,你为什么要问我们如何做一些你已经想好该怎么做的事情呢?(你希望它有多准确?无限准确?double
1赞 Tony Delroy 6/22/2015
@PanagiotisKanavos:那不一定是真的......许多金融系统使用并相信,所有累积的误差都不会达到四舍五入到美分/日元/其他任何因素后剩余的最低有效数字的影响水平。对于 ~15 位有效数字,即使“在 4 或 5 位小数计算中”存在错误,这通常也是实用的。double

答:

2赞 dlask 6/22/2015 #1

该值是可以由类型表示的最精确的近似值。11.899999611.9float

评论

0赞 Eric Postpischil 1/14/2020
它们的类型不表示 11.8999996。这就是打印的内容。float
2赞 phuclv 6/22/2015 #2

它不适用于双精度或任何其他二进制浮点类型。只需在基数点之后打印更多数字,您很快就会开始看到“垃圾”数字

唯一的方法是使用十进制浮点类型。如果您的平台有 FLT_RADIX == 10,那么您可以直接使用内置的,但显然这不是您的情况,而且我不知道除了 IBM z 系列之外,当前没有任何系统使用十进制浮点数。float

因此,您需要一个自定义类型。您可以使用一些 IEEE-754 decimal32 库,如英特尔®十进制浮点数学库libdfp。或者,如果您使用 gcc,那么它已经通过类型支持十进制浮点数_Decimal32

您可以在此问题中找到更多信息如何在 C++ 中使用十进制(浮点数)?