为什么使用 sscanf_s 或 atof 将 char * 转换为浮点数时精度会下降
Why is there a loss in precision when converting char * to float using sscanf_s or atof?
我正在尝试将仅包含浮点值的字符*转换为浮点类型,但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
当我查看类似的问题试图确定答案时,我尝试了他们的解决方案,但无济于事。
将字符*转换为浮点数或双精度
这里给出的解决方案是包含"stdlib.h",这样做之后,我将对atof的调用更改为显式调用"std::atof",但仍然没有运气。
遗憾的是,并非所有浮点值都可以以二进制形式显式表示。如果你说,你会得到同样的结果
float myValue = 2.10;
我看到评论中的出色答案丢失(或者我在那里不容易找到它)另一种如何处理它的选项。
你应该写,为什么你需要浮点数。如果您偶然碰巧使用货币金额(而不是太大的金额),您可以创建输入值的自定义解析器,并为值输出创建自定义格式化程序,将其读取为 64b 整数 (*100),并在整个应用程序中使用 100*金额值。如果您正在处理非常大量的数字,请使用一些库来处理大数字,或者您可以创建自己的库,处理字符*数字。
这是定点算术的特例。
如果你对"只是为了解决这个问题"感兴趣,不用编码太多,无论如何都要去大数字库,即使是 *100 定点变体也很容易写出错误 - 如果这是你第一次并且你没有足够的资源来正确做到这一点(TDD 建议)。
但一定要了解数字是如何存储在计算机中的,以及为什么浮点/双精度不能代表所有数字。计算机的浮点2.1
(内部使用以 2 为底)与人类的1/3
类似,如果没有无限个小数位,就不能用 10 为底表示(以及1.0
== 0.99999...
以 10 为底)。(谢谢@tobi303)
看完你的新评论,如果"这对金融应用没有太大影响吗?
答:不,零影响,没有人理智(和专业)会用浮动或双倍创建金融应用程序。
- 将浮点数转换为无符号字符数组并打印出来
- 如何将浮点数转换为uint8_t?
- 为什么C++在将浮点数转换为字符时没有显示缩小转换错误?
- 将浮点数转换为字符串时如何加快此代码的速度?
- C/C++ - 将浮点数转换为字节数组,以便字节保持排序
- 精确且无公差地将浮点数转换为字符串
- 错误:请求从 std::chrono::time_point 浮点数转换为非标量类型长整型
- 将浮点数转换为 LPCTSTR 转换
- 无法在初始化时将浮点数转换为浮点数
- 将浮点数转换为 int,带和不带强制转换
- 将浮点数转换为 int,或将 int 强制转换为浮点数
- 将浮点数转换为字符串,并指定精度和十进制数字数?
- 将范围有限的浮点数转换为无符号的整数,以保持排序顺序和精度
- 如何将浮点数转换为保留位值的整数
- 将浮点数转换为 LPCWSTR
- 正在将浮点数转换为整数定义的行为
- 将浮点数转换为整数时如何舍入
- 将浮点数转换为浮点数*
- 无需任何库函数即可将浮点数转换为字符串的有效方法
- 将浮点数转换为 4 uint8_t