Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 按零除法预防:检查除数';s表达式不';t与检查除数为'相比,结果为零;零度?_C++_Floating Point_Floating Accuracy_Floating Point Precision_Divide By Zero - Fatal编程技术网

C++ 按零除法预防:检查除数';s表达式不';t与检查除数为'相比,结果为零;零度?

C++ 按零除法预防:检查除数';s表达式不';t与检查除数为'相比,结果为零;零度?,c++,floating-point,floating-accuracy,floating-point-precision,divide-by-zero,C++,Floating Point,Floating Accuracy,Floating Point Precision,Divide By Zero,由于减法中的浮点错误,在下列情况下是否可能被零除 float x, y, z; ... if (y != 1.0) z = x / (y - 1.0); 换句话说,以下情况是否更安全 float divisor = y - 1.0; if (divisor != 0.0) z = x / divisor; 这两个代码片段之间没有区别()——事实上,优化器甚至可以将这两个片段优化为相同的二进制代码,前提是不再使用除数变量 但是,请注意,被浮点零除0.0不会导致运行时错误,而是生

由于减法中的浮点错误,在下列情况下是否可能被零除

float x, y, z;
...
if (y != 1.0)
    z = x / (y - 1.0);
换句话说,以下情况是否更安全

float divisor = y - 1.0;
if (divisor != 0.0)
    z = x / divisor;

这两个代码片段之间没有区别()——事实上,优化器甚至可以将这两个片段优化为相同的二进制代码,前提是不再使用
除数
变量


但是,请注意,被浮点零除
0.0
不会导致运行时错误,而是生成
inf
-inf

这将阻止您被精确除零,但这并不意味着仍然不会得到
+/-inf
。分母可能仍然足够小,因此答案不能用
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;
}
#包括
#包括
int main(int argc,char const*argv[]
{
double small=std::numeric_limits::epsilon();
双大=标准::数值限制::最大()/小;

std::cout假设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,但是这个定理对于大多数“合理”的浮点系统都是正确的。

对于你发布的第二个代码-你的意思是:
如果(y!=1.0)
?这两个结果是相同的(我假设你指的是除数!=0.0f,可能与y=13.0f-12.0f;(y-1.0f)不同)我相信它们是一样的。是的,永远不要检查浮点数的相等性:
y!=1.0
是禁止的。你为什么要检查
0.0
(或
1.0
)?如果
y-1.0
足够小或
x
足够大,即使是
除数!=0
,也会得到
inf
,因此这无助于防止出现这种情况,在除法后检查
inf
可能会更容易,然后计算出除法何时会给你无穷大。因此,即使两个代码路径都是相同的这对安全没有任何影响。请注意,
1.0
不是一个
float
——它是一个
double
,我不会打赌编译器会做任何明显的“显而易见”的事情浮点计算的转换,至少在没有特殊命令行标志的情况下是如此。浮点运算非常复杂。例如,它是。
y-1
永远不可能是
denorm_min()
,最小的是
-epsilon()/2
,它不会是无穷大。@KennyTM这是一个很好的观点。如果分子足够大,答案仍然可能是
inf
。我会更新我的答案。