Math 被零除:无限、NaN或零除误差?

Math 被零除:无限、NaN或零除误差?,math,programming-languages,divide-by-zero,Math,Programming Languages,Divide By Zero,为什么不是每种语言都有1/0==Inf?这不是数学上最正确的回答吗 我所熟悉的所有语言都能够表达无限值和NaN值,那么为什么它们会选择抛出错误或返回NaN呢?这只是为了让科学应用程序开发人员的生活更加艰难吗?;-) 更新:我们应该结束这个问题,因为我错误地认为Java中的1f/0f==Float.NaN。但我错了:它确实正确地返回Float.Infinity。这是我的主要困惑;一些语言抛出错误的事实是可以理解的,只要没有语言返回NaN。而1/n的极限将随着n接近零(从正方向)而趋于无穷大1/0

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

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


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

1/n
的极限将随着n接近零(从正方向)而趋于无穷大
1/0 Inf
的原因是1/0未定义(根据数学定义!)

这不是数学上最正确的回答吗

不,因为在数学中,被零除是没有定义的,无穷大通常不是一个值(或者不是一个值)


并非所有语言/库都返回NaN的原因是:(a)零除法通常是程序员错误的结果,因为它在数学上严格的算法中根本不应该出现,(b)处理器可能会通过进入异常状态来处理它,因此转换为NaN需要处理此类状态,意思是除法变得比现在更昂贵(比如说,与求和相比)。

那么
0/0
或者
-1/0
呢?如果你犯了错误怎么办?用
Inf
结果向程序发送零除信号不是一个好主意。

因为虽然
1/0
有时可能近似为
Inf
或其他类似值,但它并没有正式定义。同一正面是
10/0<20/0
?或者
0/0

分区
a | b
本身没有为
b=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
> 

浮点数是不精确的,可能非常接近零。将整数设为零可能被视为程序员的傻瓜。这可能是您看到的两种截然不同的行为。

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

结果是一个整数,根本没有办法在整数中编码“无限”。对于浮点数是没有限制的,这就是为什么在大多数语言中,浮点除法实际上会产生无穷大的值


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

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

现在考虑C=1/0。是否存在唯一的c,使得c*0=1?当然不在R或C内。如果我们引入无穷大呢?你可以有一个特例,0*Infinity=1。但是你破坏了乘法算子的一系列好的性质。也就是说,我们想要2*(0*无穷大)=2*1=2。但我们也需要关联属性。所以(2*0)*无穷=0*1

通常情况下,字段不能扩展为具有0的乘法逆,否则会保留所需的属性


也就是说,我假设你只是为了巨魔而引入了经典的1/0=无穷大。下一个问题,为什么语言不认识到0.9 repeater不等于1。

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

  • 设置可在以后测试的状态标志
  • 立即产生陷阱
第一种操作模式允许高性能,而第二种模式允许立即通知可能的有害操作

IEEE 754为引发异常的操作结果定义了一些合理的值(例如:被除数有限非零数和除数零)→ 正确符号无穷大;0/0→ 安静的南)

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

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


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

1/0始终返回无穷大,并可能引发浮点异常。0/0返回NaN,并可能引发浮点异常。@Tim Nordenfur:请参阅IEEE 754§7.1和§7.2(被除数有限的非零数字和除数零)→ 除零陷阱或正确符号无穷大;0/0→ 无效操作陷阱或静默NaN)。1/0==无穷大是一个经典的数学拖拉问题。我咬了一口,回答了一个问题,但这个问题真的会引起麻烦。@Steven但这不是一个数学网站,实际上是大多数编程语言