【问题标题】:Why does integer division by zero result in a floating point exception?为什么整数除以零会导致浮点异常?
【发布时间】:2013-05-31 12:06:52
【问题描述】:

在 C 程序中除以零会导致异常终止并显示错误消息 Floating point exception (core dumped)。这对于浮点除法来说并不奇怪,但是为什么在整数除以零时会这样说呢?整数除法是否真的使用了 FPU?

(顺便说一下,这都是在 x86 下的 Linux 上。)

【问题讨论】:

标签: c divide-by-zero


【解决方案1】:

这可能有许多不同的特定于实现的原因。

例如,x86 平台上的 FPU 单元支持浮点和整数格式来读取参数和写入结果。当平台本身是 16 位时,一些编译器使用 FPU 对 32 位整数操作数执行除法(因为 32 位宽数据没有精度损失)。在这种情况下,对于无效的 32 位整数除法得到真正的 FPU 错误并没有什么不寻常的。

【讨论】:

  • FP 异常通常被屏蔽,因此您只得到 NaN 或 +/-Inf 结果而不是异常。我想知道整数除法异常约定/传统的 SIGFPE 是否在 x86 之前开始? Unix 直到 386(保护模式)才能正确移植到 x86,但我认为存在一些没有真正内存保护的类 Unix 环境。
  • @PeterCordes 似乎 ELKS 至少尝试将 Linux 移植到 286,甚至移植到 8086。我什至在 286 机器上运行它。我想 UNIX 也可以移植。
【解决方案2】:

我对此的历史解释的猜测是原始的 unix 硬件在整数除以零时没有生成陷阱,因此名称 SIGFPE 是有道理的。 (PDP 汇编程序员,确认?)然后当系统被移植(或在 Linux 的情况下,重新实现)到具有整数除零陷阱的硬件时,添加新的信号编号被认为不值得,所以旧的获得了新的含义,现在有了一个有点混乱的名字。

【讨论】:

  • 您似乎是对的:根据this referenceDIV 指令只需将CV 标志设置为除以零,并且V 标志仅在结果不' t 适合目标寄存器。 OTOH,根据this pageFP11(PDP-11 的新 FPU)确实支持陷印。所以确实最初不需要整数除法错误信号名称。
【解决方案3】:

整数除法是否真的在底层使用了 FPU?

不,Linux 在这种情况下也只会生成 SIGFPE(它是一个旧名称,现在已经扩展了它的使用范围)。事实上,单一 Unix 规范 defines SIGFPE 是“错误的算术运算”。

【讨论】:

    【解决方案4】:

    man signal 提及:

    整数除以零有未定义的结果。在某些架构上,它会生成一个 SIGFPE 信号。 (同样将最大负整数除以 -1 可能会生成 SIGFPE。)

    【讨论】:

      猜你喜欢
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多