比较浮点数与零的标准方法是什么
What is a standard way to compare float with zero?
可能是:比较浮点数与零的标准方法是什么?
据我所知直接比较:
if ( x == 0 ) {
// x is zero?
} else {
// x is not zero??
可能会因浮点变量而失败。
我曾经使用
float x = ...
...
if ( std::abs(x) <= 1e-7f ) {
// x is zero, do the job1
} else {
// x is not zero, do the job2
...
我在这里找到的方法相同。但我看到两个问题:
- 随机幻数 1e-7f(或上面链接中的 0.00005)。
- 代码更难阅读
这是一个如此常见的比较,我想知道是否有一个标准的简短方法来做到这一点。喜欢
x.is_zero();
要将浮点值与 0 进行比较,只需比较它:
if (f == 0)
// whatever
这种比较没有错。如果它没有按照你的期望去做,那是因为f
的价值不是你想象的那样。它本质上与此相同的问题:
int i = 1/3;
i *= 3;
if (i == 1)
// whatever
这种比较没有错,但i
的值不是 1。几乎所有程序员都了解整数值的精度损失;许多人不理解浮点值。
使用"几乎相等"而不是==
是一种先进的技术;它经常导致意想不到的问题。例如,它不是可传递的;也就是说,a
几乎等于b
,b
几乎等于c
并不意味着a
几乎等于c
。
没有标准的方法,因为是否要把一个小数字当作零来处理取决于你如何计算这个数字以及它的用途。这反过来又取决于计算引入的任何误差的预期大小,也可能取决于确定原始输入的物理测量误差。
例如,假设您的值表示某些地图软件中的旅程长度(以英里为单位)。然后,您很乐意将1e-7
视为等于零,因为在这种情况下,这是一个非常小的数字:它是由于舍入误差或其他轻微不精确的原因而出现的。
另一方面,假设您的值在某些电子显微镜软件中以米为单位表示分子的大小。那么你当然不想把1e-7
看成等于零,因为在这种情况下,这是一个非常大的数字。
您应该首先考虑显示您的值的合适精度:误差线是多少,或者您可以合理显示多少有效数字。这将使您了解针对零进行测试的公差,尽管它仍然可能无法解决这种情况。对于地图软件,如果旅程小于某个固定值,您可能会将其视为零,尽管该值本身可能取决于地图的分辨率。对于显微镜软件,如果两种尺寸之间的差异为零,这些测量的95%误差范围为零,则可能仍然不足以将它们描述为相同的尺寸。
我的答案是否有用,我在 irrlicht 的 irrmath.h
中找到了这个,直到现在仍在引擎的 mathlib 中使用它:
const float ROUNDING_ERROR_f32 = 0.000001f;
//! returns if a equals b, taking possible rounding errors into account
inline bool equals(const float a, const float b, const float tolerance = ROUNDING_ERROR_f32)
{
return (a + tolerance >= b) && (a - tolerance <= b);
}
作者通过"经过多次旋转(三角运算)后,坐标破坏和直接比较可能会导致故障"来解释这种方法。
- 没有取消引用/解包对象的标准方法?
- 是否有一种标准方法来计算两个 asctime() 值之间的天数
- 导入模块的标准方法
- 有没有一种标准方法可以在C++中获取第 n 个"下一个"浮点值
- C++ 捕获异常后进行清理的标准方法是什么?
- memcpy 是将浮子打包到 uint32 中的标准方法吗?
- 读取二进制文件的惯用C++17标准方法是什么
- 在 c++ 中创建 dll 并在 delphi 中调用的标准方法
- 在 NTL 中构造多项式的标准方法是什么?
- C 是否具有对两个STD :: sets,vectors等进行三角比较的标准方法
- 获取非专用标准::矢量容器的标准方法<bool>
- 将结构传递到头文件的标准方法
- C 11中的标准方法是什么,可以访问std :: vector中元素n的指针
- 组合来自多个线程的数据的标准方法?
- 标准::字符串::空的未定义符号错误;Mac OS High Sierra 上的 c++ 标准方法链接错误
- 在C++中初始化布尔向量的标准方法是什么
- 在C 中对二进制对象进行编码/解码的标准方法
- 有没有一种标准方法来确保一段代码在全局范围内执行
- 处理对存储在私有映射中的值的封装访问的标准方法,而不破坏C++中的抽象
- 是否有一种替换C风格的Bool数组的标准方法