我们都知道0/0
是Undefined
如果我是把它变成一个计算器返回一个错误,如果我是创建一个程序(在C至少)操作系统将终止它,当我试图除以零。
但是我一直想知道的是,计算机是否试图除以零,或者它只是具有“内置保护”,这样当它“看到” 0/0
时甚至在尝试计算之前就返回错误?
我们都知道0/0
是Undefined
如果我是把它变成一个计算器返回一个错误,如果我是创建一个程序(在C至少)操作系统将终止它,当我试图除以零。
但是我一直想知道的是,计算机是否试图除以零,或者它只是具有“内置保护”,这样当它“看到” 0/0
时甚至在尝试计算之前就返回错误?
Answers:
CPU具有内置检测功能。大多数指令集体系结构都指定CPU将捕获到一个异常处理程序,以将整数除以零(我不关心除数是否为零)。
零除数的检查可能与尝试进行除法的操作在硬件中并行发生,但是,对有问题的条件的检测实际上会取消除法并捕获陷阱,因此我们无法真正确定是否有一部分它是否尝试了分裂。
(硬件通常是这样工作的,并行执行多项操作,然后选择合适的结果,因为这样每个操作都可以立即开始,而无需序列化选择合适的操作。)
当打开溢出检测功能时,也将使用相同的异常捕获机制,通常使用不同的add / sub / mul指令(或这些指令上的标志)来请求该机制。
浮点除法还内置了零除法检测功能,但是返回一个不同的值(IEEE 754指定NaN),而不是捕获到异常处理程序。
假设地说,如果CPU忽略了任何试图除以零的检测,则问题可能包括:
这取决于语言,编译器,使用的是整数还是浮点数,等等。
对于浮点数,大多数实现使用IEEE 754标准,其中很好地定义了除以0。0/0给出NaN(非数字)的明确定义的结果,而x≠0的x / 0给出+ Infinity或-Infinity,具体取决于x的符号。
在像C,C ++等语言中,被零除会调用未定义的行为。因此,根据语言定义,任何事情都可能发生。尤其是您不想发生的事情。就像编写代码时一切正常,当客户使用代码时销毁数据一样。因此,从语言角度来看,不要这样做。某些语言可确保您的应用程序崩溃。如何实现这取决于他们。对于这些语言,除以零将崩溃。
许多处理器具有某种内置的“除法”指令,具体取决于处理器的行为。在Intel 32位和64位处理器上,当您尝试除以零时,“除法”指令将使应用程序崩溃。其他处理器的行为可能有所不同。
如果编译器在执行某些代码时检测到将被零除,并且编译器对其用户友好,则它可能会向您发出警告,并生成内置的“除”指令,从而使行为为相同。
EXCEPTION_INT_DIVIDE_BY_ZERO
值,该值EXCEPTION_RECORD
将由(希望)安装的结构异常处理处理程序处理
但是我一直想知道的是,计算机是否试图除以零,或者它只是具有“内置保护”,这样当它“看到” 0/0时,甚至在尝试计算之前都会返回错误?
由于x/0
没有意义,所以计算机必须始终检查除以零。这里有一个问题:程序员希望进行计算(a+b)/c
而不必费心检查该计算是否有意义。对于由CPU +数字类型+操作系统+语言除以0的幕后反应是要么做得太激烈(例如使程序崩溃),要么做得过分良性(例如,创建一个不使之成为零的值)。 (例如IEEE浮点数NaN
,即不是数字的数字)。
在通常的情况下,程序员应该知道是否(a+b)/c
有意义。在这种情况下,没有理由检查是否被零除。如果确实发生了被零除的情况,并且如果机器语言+实现语言+数据类型+操作系统对此做出的响应是使程序崩溃,则可以。如果响应是创建一个可能最终污染程序中每个数字的值,那也是可以的。
在高可靠性计算领域,“大刀阔斧”或“过度良性”都不是正确的选择。这些默认响应可能会杀死患者,使客机坠毁或在错误的地方炸弹爆炸。在高可靠性环境中,编写(a+b)/c
代码的程序员会在代码审查期间被处死,或者在现代,可能会通过检查Verboten构造的工具自动将其处死。在这种环境下,该程序员应该改写一些类似的东西div(add(a,b),c)
(可能还需要检查错误状态)。在引擎盖下,div
(以及add
)函数/宏可防止被零除(或的情况下溢出add
)。保护所需要的是非常特定于实现的。
我们现在知道x/0
,并0/0
没有明确的答案。如果0/0
仍然尝试进行计算会怎样?
在现代系统上,计算被传递到CPU内的MPU,并被标记为非法操作,返回NaN
。
在更老的系统上,例如80年代没有片上划分的家用计算机,计算是通过运行的任何软件完成的。有几种可能的选择:
0
1
log(0)
并且该软件将使用其错误处理例程或崩溃0
和e 0 = 1,结果为1
换句话说,将取决于实现方式,并且将可能编写出能够为每个值产生正确且可预测的结果的软件,但是0/0
尽管如此,看起来似乎有些奇怪的值仍然是内部一致的。
NaN
。
very inefficient
用于除法。算术成本为(加法=减法)<=乘法<=除法。如果没有MPU可以在与加法(通常是一个)相同的时钟周期数内进行除法,那么除法运算要比加法和减法昂贵,并且通常也要比乘法更昂贵。