【问题标题】:IEEE 754, division by zeroIEEE 754,除以零
【发布时间】:2019-07-06 03:10:03
【问题描述】:

我知道在标准 IEEE 754 中除以零是允许的。我想知道它是如何用二进制表示的。

例如,十进制的 0.25 是 0 01111101 00000000000000000000000 在二进制。 5.0/0.0 或 0.0/0.0 它们在二进制中有表示吗,它们是一样的吗? 谢谢。

【问题讨论】:

    标签: ieee-754 divide-by-zero


    【解决方案1】:

    当你将一个有限数除以零时,你会得到一个无穷大,它带有你试图除的数字的符号。所以 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) 部分。

    【讨论】:

      【解决方案2】:

      Mark 纠正了我在 IEEE 754-2208 中除以零会导致正无穷或负无穷。

      在有关该主题的维基百科文章中,我们发现以下内容:

      sign = 0 表示正无穷,1 表示负无穷。

      有偏指数 = 全为 1。

      分数 = 全 0 位。

      来源:IEEE 754 Wikipedia article

      我错误地认为它会导致 NaN,我将在下面详细说明。

      +无穷大:

      0 11111111 00000000000000000000000
      

      -无穷大:

      1 11111111 00000000000000000000000
      

      以下原始回复不正确

      可能仍然是无关紧要的,因此请保留它。


      据我了解,这导致NaN,pr **不是数字*。

      Nan 上的维基百科页面有一个编码部分,以下引用来自该部分。

      在符合 IEEE 754 标准的浮点存储格式中,NaN 由 NaN 独有的特定预定义位模式标识。 符号位无关紧要。二进制格式的 NaN 用 用 1 填充的指数字段(如无穷大值)和一些 非零数字表示有效数(使它们与无穷大值不同)。 1985 年的原始 IEEE 754 标准 (IEEE 754-1985) 仅描述了二进制浮点格式,并没有指定如何标记信号/静默状态。在实践中,有效位的最高有效位决定了 NaN 是发信号还是静默。产生了两种不同的实现,具有相反的含义。

      来源:NaN Encoding (Wikipedia)

      文章还继续指出,在 2008 年,IEEE 754-2008 修订版添加了一种建议的方法来指示 NaN 应该是安静还是冗长。

      NaN 通过将符号位之后的组合字段的前五位设置为 1 来标识。该字段的第六位是“is_quiet”标志。该标准遵循“is_signaling”标志的解释。 IE。如果 NaN 是安静的,则信号/安静位为零,如果通过使 aN 是信令来识别 N,则非零。

      基本上和以前一样,指数都是1,最后一位表示是否安静。

      我的解释是 NaN 可以用多种方式表示,包括如下:

      0 11111111 00000000000000000000010
      

      【讨论】:

      • 一些不准确之处:在默认异常处理下,将非零有限数除以零将给出适当符号的无穷大(不是 NaN)。您引用的第二段与 OP 使用的 decimal32 格式而不是 binary32 格式有关。 (只有十进制浮点格式具有组合指数和有效数字信息的“组合字段”。)
      • 谢谢@MarkDickinson,你是完全正确的。修改了我的答案。
      猜你喜欢
      • 2019-05-11
      • 2015-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-07
      • 2012-01-06
      • 2012-03-14
      相关资源
      最近更新 更多