使用sscanf_s或atof将char *转换为float时,为什么会出现精度损失?

时间:2016-07-11 16:41:11

标签: c++ precision scanf atof

我试图将只包含浮点值的char *转换为float类型,但sscanf_s和atof都会产生相同的无效结果。

char t[] = "2.10";
float aFloat( 0.0f ), bFloat( 0.0f );

sscanf_s( t, "%f", &aFloat );
bFloat = atof( t );

输出:

aFloat: 2.09999990
bFloat: 2.09999990

当我查看类似的问题以试图确定答案时,我尝试了他们的解决方案无济于事。

Converting char* to float or double

这里给出的解决方案是包含'stdlib.h',在这之后我将对atof的调用更改为显式调用'std :: atof',但仍然没有运气。

2 个答案:

答案 0 :(得分:3)

不幸的是,并非所有浮点值都可以以二进制形式显式表示。如果你说

,你会得到相同的结果
float myValue = 2.10;

答案 1 :(得分:3)

我看到评论中的优秀答案缺失(或者我没有在那里轻易找到)另一种选择如何处理它。

你应该写了,为什么你需要浮点数。如果您偶然碰巧使用金额(而不是太大的金额),您可以创建输入值的自定义解析器和值输出的自定义格式化程序,将其读取为64b整数(* 100),并在您的整体工作具有100 *金额值的应用程序。如果您正在使用非常大的数量,请使用一些库来获取大数字,或者您可以创建自己的库,使用char *数字。

这是Fixed-point arithmetic的一个特例。

如果你对#34;只是为了解决这个问题而没有编码过多,那么无论如何都要去大数字库,即使是* 100定点变体很容易用错误编写 - 如果它&# 39;这是你第一次没有足够的资源来做正确的事(建议TDD)。

但绝对要知道数字是如何存储在计算机中的,以及为什么float / double不能代表所有数字。用于计算机的浮动2.1(内部使用的基础2)与人类1/3的情况类似,不能在没有无限小数位数的情况下在基数10中表示(以及如何{基数10中的{1}} == 1.0。 (感谢@ tobi303)

阅读新评论后,如果"这对财务应用程序没有太大影响吗?"

答案:nope,零影响,没人理智(和专业)会创建浮动或双打的财务应用程序。