【发布时间】:2019-07-06 03:10:03
【问题描述】:
我知道在标准 IEEE 754 中除以零是允许的。我想知道它是如何用二进制表示的。
例如,十进制的 0.25 是
0 01111101 00000000000000000000000
在二进制。 5.0/0.0 或 0.0/0.0 它们在二进制中有表示吗,它们是一样的吗?
谢谢。
【问题讨论】:
我知道在标准 IEEE 754 中除以零是允许的。我想知道它是如何用二进制表示的。
例如,十进制的 0.25 是
0 01111101 00000000000000000000000
在二进制。 5.0/0.0 或 0.0/0.0 它们在二进制中有表示吗,它们是一样的吗?
谢谢。
【问题讨论】:
当你将一个有限数除以零时,你会得到一个无穷大,它带有你试图除的数字的符号。所以 5.0/0.0 是 +inf 但 0.0/0.0 返回一个称为 QNaN 不定值的东西。
假设我们将负一除以零。因为这会导致预先计算的异常,我认为理解发生了什么的关键在于英特尔在第 4.9.1.2 节中使用的“响应”措辞
被零除异常的掩码响应是设置 ZE 标志并返回一个用操作数符号的异或符号表示的无穷大。
我希望我没看错。由于零掩码位(在 x87 FPU 的控制字中找到)为 1,因此一旦 fpu 在用于除法的操作数中检测到零,预计算的异常标志就会置位。现在处理器知道要做这样的事情了:
操作数 1 的 1 个符号,我们的 -1.0 xor 0 操作数 2 的符号,零 ---------- 1 条回复现在有了那个响应位,我知道我是正无穷还是负无穷
-inf 1 11111111 00000000000000000000000 -----+-+------+-+----------+ | | | | | | +--------+ +----------+ | | | | v v |指数分数 | v 符号如果我得到一个正数 1.0 并除以零:
0 操作数 1 的符号 xor 0 操作数 2 的符号 ------------ 0现在我有
inf 0 11111111 00000000000000000000000
只要分子是正数并且除以零,就会得到相同的正无穷大。 这就是我想象当我运行这样的事情时会发生的事情:
int main() {
SetExceptionMask(exAllArithmeticExceptions);
float a = -1;
float b = a / 0.0f;
printf("%f\n", b);
}
结果是-inf,看起来像这样1 11111111 00000000000000000000000
QNaN(“安静的不是数字”)对调试特别有帮助,可以通过几种不同的方式生成,但 0.0/0.0 会返回如下所示的内容:
qnan 0 11111111 100000000000000000000000 -----+-+------+-+----------+ | | +----------+ | v 分数现在软件可以出于任何目的操纵 QNaN 小数部分中的位,通常这似乎是出于诊断目的。 要了解更多信息,我建议您阅读英特尔手册的第 31(https://youtu.be/SsDoUirLkbY) 和 33(https://youtu.be/3ZxXSUPSFaQ) 部分。
【讨论】:
Mark 纠正了我在 IEEE 754-2208 中除以零会导致正无穷或负无穷。
在有关该主题的维基百科文章中,我们发现以下内容:
sign = 0 表示正无穷,1 表示负无穷。
有偏指数 = 全为 1。
分数 = 全 0 位。
我错误地认为它会导致 NaN,我将在下面详细说明。
+无穷大:
0 11111111 00000000000000000000000
-无穷大:
1 11111111 00000000000000000000000
以下原始回复不正确
可能仍然是无关紧要的,因此请保留它。
据我了解,这导致NaN,pr **不是数字*。
Nan 上的维基百科页面有一个编码部分,以下引用来自该部分。
在符合 IEEE 754 标准的浮点存储格式中,NaN 由 NaN 独有的特定预定义位模式标识。 符号位无关紧要。二进制格式的 NaN 用 用 1 填充的指数字段(如无穷大值)和一些 非零数字表示有效数(使它们与无穷大值不同)。 1985 年的原始 IEEE 754 标准 (IEEE 754-1985) 仅描述了二进制浮点格式,并没有指定如何标记信号/静默状态。在实践中,有效位的最高有效位决定了 NaN 是发信号还是静默。产生了两种不同的实现,具有相反的含义。
文章还继续指出,在 2008 年,IEEE 754-2008 修订版添加了一种建议的方法来指示 NaN 应该是安静还是冗长。
NaN 通过将符号位之后的组合字段的前五位设置为 1 来标识。该字段的第六位是“is_quiet”标志。该标准遵循“is_signaling”标志的解释。 IE。如果 NaN 是安静的,则信号/安静位为零,如果通过使 aN 是信令来识别 N,则非零。
基本上和以前一样,指数都是1,最后一位表示是否安静。
我的解释是 NaN 可以用多种方式表示,包括如下:
0 11111111 00000000000000000000010
【讨论】: