除以零的结果是什么?
需要明确的是,我并不是在寻找 NaN 或无穷大,也不是在询问 x/0 的答案应该是什么。我正在寻找的是这样的:
基于硬件中除法的执行方式(我不知道它是如何完成的),如果除法以除数 0 执行,并且处理器只是愉快地完成该操作,会产生什么结果?
我意识到这高度依赖于除数,因此对于具体答案,我会问:如果计算机遵循 42 / 0
上的标准除法运算,它会输出什么?
更新:
我会尽量说得更清楚一些。我询问的是在位级别上对数字进行的实际操作以得出解决方案。运算的结果只是位。当发现除数为零时,NaN 和错误/异常就会发挥作用。如果分裂真的发生,会产生什么结果?
To be clear, I am not looking for NaN or infinity, or asking what the answer to x/0
should be. What I'm looking for is this:
Based on how division is performed in hardware (I do not know how it is done), if division were to be performed with a divisor of 0, and the processor just chugged along happily through the operation, what would come out of it?
I realize this is highly dependent on the dividend, so for a concrete answer I ask this: What would a computer spit out if it followed its standard division operation on 42 / 0
?
Update:
I'll try to be a little clearer. I'm asking about the actual operations done with the numbers at the bit level to reach a solution. The result of the operation is just bits. NaN and errors/exceptions come into play when the divisor is discovered to be zero. If the division actually happened, what bits would come out?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
它可能只是不会停止。整数除法可以通过重复减法在线性时间内进行:对于 7/2,您可以用 7 减去 2 总共 3 次,这就是商,余数(模)为 1。如果您要提供一个0 的被除数到这样的算法中,除非有适当的机制来阻止它,否则该算法不会停止:您可以从 42 中减去 0 无数次而不会得到任何结果。
从类型的角度来看,这应该是直观的。未定义计算或不间断计算的结果是⊥(“底部”),每个类型中都有未定义的值。整数上没有定义被零除,因此它应该通过引发错误或无法终止来正确地产生 ⊥ 。前者可能更可取。 ;)
其他更有效的(对数时间)除法算法依赖于收敛到商的级数;对于 0 的股息,据我所知,这些将无法收敛(即无法终止)或产生 0。请参阅 维基百科上的部门。
浮点除法同样需要一个特殊情况:将两个浮点数相除,减去它们的指数并整数除它们的有效数。相同的底层算法,相同的问题。这就是为什么 IEEE-754 中有正无穷大和负无穷大以及有符号零和 NaN(0/0)的表示。
It might just not halt. Integer division can be carried out in linear time through repeated subtraction: for 7/2, you can subtract 2 from 7 a total of 3 times, so that’s the quotient, and the remainder (modulus) is 1. If you were to supply a dividend of 0 to an algorithm like that, unless there were a mechanism in place to prevent it, the algorithm would not halt: you can subtract 0 from 42 an infinite number of times without ever getting anywhere.
From a type perspective, this should be intuitive. The result of an undefined computation or a non-halting one is ⊥ (“bottom”), the undefined value inhabiting every type. Division by zero is not defined on the integers, so it should rightfully produce ⊥ by raising an error or failing to terminate. The former is probably preferable. ;)
Other, more efficient (logarithmic time) division algorithms rely on series that converge to the quotient; for a dividend of 0, as far as I can tell, these will either fail to converge (i.e., fail to terminate) or produce 0. See Division on Wikipedia.
Floating-point division similarly needs a special case: to divide two floats, subtract their exponents and integer-divide their significands. Same underlying algorithm, same problem. That’s why there are representations in IEEE-754 for positive and negative infinity, as well as signed zero and NaN (for 0/0).
对于具有内部“除”指令的处理器(例如带有
div
的 x86),如果尝试除以零,CPU 实际上会导致软件中断。该软件中断通常被语言运行时捕获并转换为适当的“除以零”异常。For processors that have an internal "divide" instruction, such as the x86 with
div
, the CPU actually causes a software interrupt if one attempts to divide by zero. This software interrupt is usually caught by the language runtime and translated into an appropriate "divide by zero" exception.硬件除法器通常使用流水线长除法结构。
假设我们现在讨论的是整数除法(而不是浮点数);长除法的第一步是对齐最重要的部分(在尝试从被除数中减去除数之前)。显然,在 0 的情况下这是未定义的,所以谁知道硬件会做什么。如果我们假设它做了正常的事情,下一步就是执行 log(n) 减法(其中 n 是位位置的数量)。对于每次产生正结果的减法,都会在输出字中设置 1。所以这一步的输出将是一个全 1 的单词。
浮点除法需要三个步骤:
0 由全 0 表示(尾数和指数)。然而,尾数中总是有一个隐含的前导 1,因此如果我们不将此表示视为特殊情况,它看起来和表现得就像一个极小的 2 的幂。
Hardware dividers typically use a pipelined long division structure.
Assuming we're talking about integer division for now (as opposed to floating-point); the first step in long division is to align the most-significant ones (before attempting to subtract the divisor from the dividend). Clearly, this is undefined in the case of 0, so who knows what the hardware would do. If we assume it does something sane, the next step is to perform log(n) subtractions (where n is the number of bit positions). For every subtraction that results in a positive result, a 1 is set in the output word. So the output from this step would be an all-1s word.
Floating-point division requires three steps:
0 is represented by all-0s (both the mantissa and the exponent). However, there's always an implied leading 1 in the mantissa, so if we weren't treating this representation as a special case, it would just look and act like an extremely small power of 2.
这取决于实施。 IEE 标准 754 浮点[1]定义了有符号无穷大值,因此理论上它应该是除以零的结果。如果除法运算中除数为零,则硬件只需设置一个标志。它没有什么魔力。
一些错误的(读作 x86)架构如果被零除的话就会抛出陷阱,从数学的角度来看,这在理论上是一种逃避。
[1] http://en.wikipedia.org/wiki/IEEE_754-2008
It depends on the implementation. IEE standard 754 floating point[1] defines signed infinity values, so in theory that should be the result of divide by zero. The hardware simply sets a flag if the demoninator is zero on a division operation. There is no magic to it.
Some erroneous (read x86) architectures throw a trap if they hit a divide by zero which is in theory, from a mathematical point of view, a cop out.
[1] http://en.wikipedia.org/wiki/IEEE_754-2008
这将是一个无限循环。通常,除法是通过连续减法完成的,就像乘法是通过连续加法完成的一样。
所以,零是特殊情况,因为我们都知道答案是什么。
It would be an infinite loop. Typically, division is done through continuous subtraction, just like multiplication is done via continual addition.
So, zero is special cased since we all know what the answer is anyway.
它实际上会抛出一个异常。从数学上讲,42 / 0 是未定义的,因此计算机不会为这些输入输出特定值。我知道除法可以在硬件中完成,但是设计良好的硬件将具有某种标志或中断来告诉您应该包含结果的寄存器中包含的任何值都是无效的。许多计算机都例外。
It would actually spit out an exception. Mathematically, 42 / 0, is undefined, so computers won't spit out a specific value to these inputs. I know that division can be done in hardware, but well designed hardware will have some sort of flag or interrupt to tell you that whatever value contained in the registers that are supposed to contain the result is not valid. Many computers make an exception out of this.
在 x86 上,发生中断 0 并且输出寄存器不变
最小 16 位实模式示例(例如要添加到引导加载程序):
如何详细运行此代码 || 32 位版本。
DIV 指令的英特尔文档没有说常规输出寄存器(ax == 结果,dx == 模块)被修改,所以我认为这意味着它们保留不变。
然后,Linux 将处理该中断,以向执行此操作的进程发送 SIGFPE,如果不处理,该进程将被终止。
On x86, interrupt 0 occurs and the output registers are unchanged
Minimal 16-bit real mode example (to be added to a bootloader for example):
How to run this code in detail || 32-bit version.
The Intel documentation for the DIV instruction does not say that the regular output registers (
ax
== result,dx
== module) are modified, so I think this implies they stay unchanged.Linux would then handle that interrupt to send a SIGFPE to the process that did that, which is will kill it if not handled.
X / 0 其中X是实数元素并且大于或等于1,
因此答案 X / 0 = 无穷大。
除法(c#)
X / 0 Where X is an element of realnumbers and is greater than or equal to 1,
therefor the answer of X / 0 = infinity.
Division method (c#)