为什么除数下限仅在除数远小于被除数时产生,如果分母接近零而不管股息的大小如何,它是否应该发生?
答案 0 :(得分:3)
来自http://www.strw.leidenuniv.nl/docs/intel/f_ug/ieee_ovw.htm
如果舍入结果具有指数,则会发生下溢异常 这太小了,无法使用浮点格式表示 结果。
这意味着当被除数和除数的比率小到足以超过浮点格式的精度时,就会发生错误,而不是对诸如epsilon之类的特定值的任何依赖。
当分母接近零时,假设分子为非零,分裂的结果将接近无穷大。当分子接近零时,假设非零分母,结果接近零。当这个值足够小时,就会出现这种情况。
如果分子和分母的值非常接近,即使它们非常小,也可以获得有用的结果,因此非常小的分子不一定会导致下溢。
示例强>:
在C#中,epsilon是1.401298E-45。
epsilon / epsilon == 1.0f
即使分子非常非常小,结果仍然是有效的浮点数。
现在,如果您尝试这样的事情:
float max = 3.40282347E+38f;
/// underflow, denominator will be 0.0f
float denominator = epsilon / max;
denominator
的订单为1e-83。由于83远超过最大单精度浮点指数,因此该值将被钳制为零。这是发生下溢的地方。
/// generates a divide-by-zero error.
float result = 10 / denominator;
这会产生除零而不是无穷大,因为存储在denominator
中的中间结果在用于第二次操作之前首先被钳位为0.
是否获得下溢或除零可能取决于编译器,您的使用和parenthisis的顺序等。
例如,再次在C#中:
10f / float.Epsilon / float.MaxValue
以及
(10f / float.Epsilon) / float.MaxValue
给出20971522.0f。
然而,数学上的等式表达式:
10f / (float.Epsilon / float.MaxValue)
给出无限。