繁体   English   中英

为什么int和decimal抛出DivideByZeroException而浮点数却没有?

[英]Why do int and decimal throw DivideByZeroException but floating point doesn't?

根据http://msdn.microsoft.com/en-us/library/system.dividebyzeroexception.aspx,只有当你将它们除以0时,Int和Decimal会抛出DivideByZeroException,但是当你将浮点除以0时,结果是无穷大,负无穷大或NaN。 为什么是这样? 结果是+ ve无穷大,-ve无穷大还是NaN的例子是什么?

对于可能遇到浮点数学这类问题的代码范围,IEEE标准委员会认为异常处理比它的价值更麻烦

陷阱可用于停止程序,但不可恢复的情况极为罕见。
[...]
标志提供可预测的控制流程和速度。 它们的使用要求程序员了解异常情况,但标志粘性允许程序员在必要时延迟处理异常情况。

对于习惯于异常处理的语言的开发人员来说,这可能看起来很奇怪,比如C#。 IEEE 754标准的开发人员正在考虑更广泛的实现(例如,嵌入式系统),这些设施不可用,或者不可取。

迈克尔的答案当然是正确的。 这是另一种看待它的方式。

整数是准确的。 当你用整数除七,你实际上问的问题是“在我必须进入负数之前,我可以从七减去三次?”。 除零是未定义的,因为没有多少次你可以从七中减去零以得到负面的东西。

漂浮物本质上是不精确的。 它们具有一定的精度,您最好假设“实际”数量介于给定的浮点数和它附近的浮点数之间。 此外,浮点数通常表示物理量,而那些浮点数的测量误差远大于表示误差。 我认为漂浮物是一个模糊的涂抹区域,围绕着一个点。

因此,当您在浮点数中将7除以零时,可以将其视为将某个数字合理地接近7除以合理接近零的某个数字。 显然,一个合理接近零的数字可以使商数任意大! 因此,通过给予无限作为答案,这向你发出信号; 这意味着答案可能是任意大的,取决于真实值的实际位置。

内置于处理器中的浮点引擎非常能够生成浮点除以零的异常。 Windows有一个专用的异常代码,STATUS_FLOAT_DIVIDE_BY_ZERO,异常代码0xC000008E,“浮点除零”。 以及FPU可以报告的其他事故,例如溢出,下溢和不精确的结果(也称为非正规)。

无论是否由控制寄存器决定,程序都可以使用辅助函数(如_controlfp())更改此寄存器。 使用Borland工具创建的库通常会执行此操作,例如,取消屏蔽这些异常。

说得好,说得好。 这是你能想象到的最糟糕的全局变量。 将这些库与期望被零除以生成无穷大而不是异常的其他库混合起来不起作用,并且几乎不可能处理。

因此,语言运行时现在是掩盖所有浮点异常的标准。 CLR也坚持这一点。

处理取消屏蔽异常的库是很棘手的,但有一个愚蠢的解决方法。 您可以抛出异常并再次捕获它。 CLR中的异常处理代码重置控制寄存器。 这个答案显示了这方面的一个例子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM