c++ - 将浮点数转换为双倍时精度损失
问题描述
我想我的 c++ 程序遇到了精度问题。而且我不明白为什么我的价值观会得到不同的结果。
res
等于1321.0000001192093
如果我写:
float sy = -0.207010582f;
double res = -1512.*((double)sy - (2. / 3.));
但 res2 等于1320.9999999839999
如果我写:
double res2 = -1512.*(-0.207010582 - (2. / 3.));
当我写这个时,为什么甚至 syd 与 syd2 不同:
double syd = -0.207010582f;
double syd2 = -0.207010582000000000;
有人可以帮我一把,将我的浮动正确地转换成双倍并了解发生了什么吗?
解决方案
单精度
正如其他人所说,float sy = -0.207010582f;
从单精度浮点文字初始化单精度(32 位)浮点变量。
这将被视为(在存储和计算中)该格式中最接近的可表示数字。这个数字是-0.20701058208942413330078125
你的代码是有效的float sy = -0.20701058208942413330078125;
您可以通过查看相邻的单精度浮点数来确认这是最接近的可表示值。
-0.20701059699058532714843750 // std::nextafter( sy, std::numeric_limits<float>::lowest() )
-0.20701058208942413330078125 // sy
-0.20701056718826293945312500 // std::nextafter( sy, std::numeric_limits<float>::max() )
双精度
双精度浮点数的情况完全相同,只是它们的分辨率提高意味着差异很小。egdouble dy = -0.207010582;
实际上代表值0.20701058199999999853702092877938412129878997802734375
同样,可以表示的相邻值是——
-0.2070105820000000262925965444082976318895816802978515625 // std::nextafter( dy, std::numeric_limits<double>::lowest() )
-0.2070105819999999985370209287793841212987899780273437500 // dy
-0.2070105819999999707814453131504706107079982757568359375 // std::nextafter( dy, std::numeric_limits<double>::max() )
单到双转换
所有单精度浮点值都可以用双精度精确表示。因此,从单精度到双精度的转换不会丢失任何内容。
以上所有假设 IEEE754 浮点表示。
推荐阅读
- kubernetes - Pod 因内存或 OOMKilled 而被驱逐
- git - 如何将新更改转发到 1 个月前的功能分支
- laravel - 如何在 Laravel 中显示多个有价值的列
- powershell - 新行和/或回车未转换
- laravel - Laravel 查询排序与 2 个表
- sql - CASE 表达式在 SQL Server 中有效,但在 Visual Studio Reporting Services 中无效
- unity3d - Agora Unity - PushAudioFrame
- excel - 使用集合时过程调用或参数无效
- jmeter - 为什么 JMeter 服务测试不稳定?
- ldap - 需要有关使用 Ldap 高可用性杂项检查脚本的 keepalived 的帮助