除以零:无限,NaN或零分割误差?

时间:2011-07-03 15:34:05

标签: math programming-languages divide-by-zero

为什么每种语言都没有1/0 == Inf?这不是数学上最正确的反应吗?

我熟悉的所有语言都能够表达无限和NaN值,那么为什么他们会选择抛出错误或返回NaN呢?是否只是让科学应用程序开发人员的生活变得更难? ; - )

更新:我们应该关闭这个问题,因为我错误地认为Java中的1f/0f == Float.NaN。但我错了: 正确返回Float.Infinity。这是我的主要困惑;只要没有语言返回NaN,一些语言抛出错误的事实是可以理解的。

9 个答案:

答案 0 :(得分:17)

除了1/0 == inf在数学上非常值得怀疑之外,它在大多数编程语言中不起作用的简单原因是1 / 0执行整数除法几乎普遍存在(存在例外)。

结果是整数,并且根本无法在整数中编码“无穷大”。有浮点数,这就是浮点除法在大多数语言中实际产生无限值的原因。

对于NaN也是如此:虽然IEEE浮点标准定义了表示NaN值的位模式,但整数没有这样的值;因此,这些值根本不能表示为整数。

答案 1 :(得分:3)

虽然当{n}接近零(从正方向)时,1 / n的极限将倾向于无穷大,1 / 0 <> Inf是1/0的原因未定义(通过数学定义!)。

答案 2 :(得分:3)

  

这不是数学上最正确的反应吗?

不,因为在数学中,除零是简单的未定义,无穷大通常不是一个值(或不是单个值)。

并非所有语言/库都返回NaN的原因是(a)零分割通常是程序员错误的结果,因为它不应该在数学上严格的算法中发生,并且(b)处理器可能处理通过进入异常状态,转换为NaN需要处理这些状态,这意味着分割变得比现在更加昂贵(比较,比较,总结)。

答案 3 :(得分:2)

为什么要拖钓?但我会咬人。这可能会因您构建运算符的方式而异,但最常用的定义除法的方法只是乘法的函数逆。也就是说,c = a / b被定义为c是唯一数,使得c * b = a。

现在考虑c = 1/0。是否有一个独特的c,c * 0 = 1?当然不在R或C内。如果我们引入无穷大?你可以有一个特殊情况,说0 * Infinity = 1.但是你打破了乘法运算符的一堆很好的属性。那就是我们想要2 *(0 * Infinity)= 2 * 1 = 2.但我们也想要关联属性。所以(2 * 0)*无穷大= 0 *无穷大= 1。

一般情况下,无论如何都不能将Field扩展为具有0的乘法反函数,以保留所需的属性。

那就是说,我假设你将经典的1/0 = Infinity引入了巨魔。下一个问题,为什么语言不能识别0.9转发器不等于1。

答案 4 :(得分:1)

0/0-1/0怎么样?如果你弄错了怎么办?用Inf结果表示程序零除法不是一个好主意。

答案 5 :(得分:1)

浮点运算可以检测几种异常情况,并以几种不同的方式作出反应:

  • 设置可以在以后测试的状态标志。
  • 立即生成陷阱。

第一种操作模式允许高性能,而第二种模式允许立即通知可能的错误操作。

IEEE 754为引发异常的操作结果定义了一些合理的值(例如:dividend有限非零数和除数零→正确签名的INFINITY; 0/0→Quiet NaN)。

带有陷阱的IEEE 754意图是,将有用户模式处理程序可以检查操作,操作数(用于无效操作和除零除异常)或结果(用于溢出,下溢和不精确异常)和异常标志并返回一个新的用户定义结果。

实际上,有些语言甚至不支持访问异常状态标志,更不用说设置陷阱处理程序了。

即使C为陷阱处理程序提供了非常原始的支持,C99甚至没有定义一种设置陷阱模式的可移植方式,例如:将一些实现定义的值传递给fesetenv()。实现通常会引发SIGFPE,用户通常需要访问依赖于CPU的状态来实现类似IEEE-754的陷阱处理程序。

答案 6 :(得分:0)

因为虽然1 / 0有时可能近似为INF或某些其他类似值,但它并未正式定义为此类。同一方面是10 / 0 < 20 / 0?或0 / 0

答案 7 :(得分:0)

a | b没有为b = 0定义{{1}}。因此,此操作的实现将此案例映射到特殊值,以表达此概念。

答案 8 :(得分:0)

在Java交互窗格中,我看到了这一点。

Welcome to DrJava.  Working directory is /Users/morrison/Desktop/PhotoPuzzle
> int top = 1;
> int bottom = 0;
> top/bottom
java.lang.ArithmeticException: / by zero
> double topFloat = 1;
> double bottomFloat = 0;
> topFloat/bottomFloat
Infinity
> 

浮点数不精确,可能非常接近于零。使整数为零可能被视为程序员的蠢事。这些可能是您看到的两种截然不同的行为。