在std::remainder()调用双精度体后检测零
Detect zero after std::remainder() call on doubles
我有这样的代码:
double a = remainder(92.66, 0.01);
double b = remainder(92.87, 0.01);
结果是a = -5.33948e-15
和b = -2.61423e-15
这里的答案显然是零,如果我把两个数都乘以100,然后做整数模数,它将是。但我想用双精度来做这个。问题是,余数返回一个比DBL_EPSILON大的数字-那么确定a
或b
是否为零的正确(最佳近似)方法是什么?
DBL_EPSILON
是1.0可以加的最小的数量。如果您的数字大于1.0,那么该数字的epsilon也将成比例地大。只需将DBL_EPSILON
乘以数字即可获得阈值。
double a = remainder(92.66, 0.01);
if (a <= DBL_EPSILON * 92.66)
a = 0.0;
比较浮点数是否相等是困难的。特别是和0比较。这是直接从一篇有用的博客文章中复制的等式函数,你应该阅读一下。根据需要将float替换为double,或者创建模板。
bool AlmostEqualRelativeAndAbs(float A, float B,
float maxDiff, float maxRelDiff)
{
// Check if the numbers are really close -- needed
// when comparing numbers near zero.
float diff = fabs(A - B);
if (diff <= maxDiff)
return true;
A = fabs(A);
B = fabs(B);
float largest = (B > A) ? B : A;
if (diff <= largest * maxRelDiff)
return true;
return false;
}
现在需要计算maxDiff
和maxRelDiff
参数的拟合值。它们取决于你执行的计算有多不稳定。可能不会比几个DBL_EPSILON
多多少。
你的问题是你的数字不能被机器精确地表示。您可以在代码中看到数字0.01、92.66和92.87。计算机看不到它们。它看到机器可以表示的最接近0.01、92.66和92.87的数字。
当你要求计算余数时,它会计算这些表示的余数,而不是你指定的原始数字的余数。
您必须根据您的应用程序使用多种方法中的一种来比较浮点数与零。
相关文章:
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 正在将csv文件读取为双精度矢量
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 如何在C++中的同一函数中使用字符串和双精度
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 检查是否以特定精度给出双精度
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- C 字符串返回字符串的整数/双精度/长整型值
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- 如何使双精度值的 C++ 和 C# 中的结果相同
- 使用浮点数和双精度数的非常小数字的数学
- 使用 Xcode 将双精度存储在数组C++中
- 在 C++ 中将双精度变量写入二进制文件
- 如何从字符串转换为双精度*
- 为什么我的数组双精度函数不起作用?
- 高精度双精度的 Sprintf 格式化问题
- C++ cout 将双精度对齐到精度 2 并正确对齐
- 在std::remainder()调用双精度体后检测零
- 如何检测双精度浮点溢出和下溢
- 使用 C++,有没有办法检测浮点/双精度非正态化是否被编译器/系统"规范化"?