Max*_*Max 7 c++ floating-point floating-accuracy divide-by-zero floating-point-precision
由于减法中的浮点误差,在以下情况下是否可以除零?
float x, y, z;
...
if (y != 1.0)
z = x / (y - 1.0);
Run Code Online (Sandbox Code Playgroud)
换句话说,以下是否更安全?
float divisor = y - 1.0;
if (divisor != 0.0)
z = x / divisor;
Run Code Online (Sandbox Code Playgroud)
假设IEEE-754浮点数,它们是等价的.
这是FP算法的基本定理,对于有限x和y,x - y == 0当且仅当x == y时,假设逐渐下溢.
如果将次正规结果刷新为零(而不是逐渐下溢),则该定理仅在结果x-y正常时才成立.因为1.0被很好地缩放,y - 1.0所以永远不是正常的,因此y - 1.0当且仅当y恰好是1.0时才是零,无论如何处理下溢.
当然,C++并不保证IEEE-754,但对于大多数"合理的"浮点系统来说,这个定理都是正确的.
这样可以防止你将其精确地除以零,但这并不意味着仍然不会因此而结束+/-inf.分母可能仍然足够小,所以答案是不能代表a double,你最终会得到一个inf.例如:
#include <iostream>
#include <limits>
int main(int argc, char const *argv[])
{
double small = std::numeric_limits<double>::epsilon();
double large = std::numeric_limits<double>::max() / small;
std::cout << "small: " << small << std::endl;
std::cout << "large: " << large << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这个程序中small是非零的,但它是如此之小,large超过的范围double和是inf.