程序中明显的浮点错误C++
Blatant floating point error in C++ program
我正在为double
变量分配一个双精度文字。 变量的值被截断,否则我不明白为什么,例如diff
差为 0.0。
很抱歉setprecision
的代码重复,但我真的很生气。
#include <iostream>
#include <iomanip>
#include <cmath>
#include <limits>
int main()
{
long double d = 1300010000000000000144.5700788999;
long double d1 = 1300010000000000000000.0;
long double diff = d - d1; // shall be 144.5700788999!!!
long double d2 = 0.5700788999;
std::cout << "d = " << std::fixed << std::setprecision(std::numeric_limits<long double>::digits10 + 1) << d << 'n';
std::cout << "d1 = " << std::fixed << std::setprecision(std::numeric_limits<long double>::digits10 + 1) << d1 << 'n';
std::cout << "d - d1 = " << std::fixed << std::setprecision(std::numeric_limits<long double>::digits10 + 1) << diff << 'n';
std::cout << "d2 = " << std::fixed << std::setprecision(std::numeric_limits<long double>::digits10 + 1) << d2 << 'n';
}
这是输出:
d = 1300009999999999900000.0000000000000000
d1 = 1300009999999999900000.0000000000000000
d - d1 = 0.0000000000000000
d2 = 0.5700788999000001
我希望diff
144.5700788999
但这很0.0
那么,该如何应对呢?(窗口 7 及更高版本,VS 2013)
。使用两个双精度,一个用于高值,一个用于低值? 就像,而是使用d
来使用d1
和d2
?
80 位long double
(不确定其在 MSPS 中的大小)可以存储大约 18 个有效的十进制数字而不会损失精度。1300010000000000000144.5700788999
有 32 个有效的十进制数字,不能完全按照long double
存储。
有关更多详细信息,请参阅往返转换所需的位数。
好吧,你面对的是浮点的狂野西部!不要相信任何人,不要期望太多,把手放在你的枪上。
问题是:浮点表示是一个分裂。给定的字节量用于存储两个部分,尾数值和第十次方(当然是简化的描述,但它足以满足我们在这里的需求)。一旦你的值太大而无法放入尾数,计算机该怎么办?它必须将其余部分带到字节的另一部分(就像大数学库所做的那样),或者只是四舍五入到最接近的值。让我展示一下:
d2 = 0.5700788999; // shows 0.5700788999000001
d2 = 1300010000000000000000.5700788999; // shows 1300009999999999934464.0000000000000000000
嘿,我在第二种情况下的小数部分在哪里?不见了!报警!哦,等等,它只是不适合...这就是为什么 diff 给出零的原因:螳螂是如此之大,以至于尾部(实际差异所在)无法存储。一旦其余数字相同,我们的差异为零。
仔细比较后,您可以发现另一件事:打印值接近分配的值,但有点不同。这是因为尾数只是 2 的幂之和。因此,为了表示值,计算机必须将分配的值舍入到最接近二进制兼容的值。这有时是另一种痛苦,您不应该通过相等运算符比较浮点数,只需评估差异并将其与预期精度的预期增量进行比较。
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 在某些循环内使用vector.push_back时出现分段错误
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 错误:未在此范围内声明'reverse'