为什么这个程序中有浮点异常? #包括 int main() { int i; INTC; INTA[30]={5,7,11,13,17,19,23,29,31,37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131 }; 对于(i=0;i

为什么这个程序中有浮点异常? #包括 int main() { int i; INTC; INTA[30]={5,7,11,13,17,19,23,29,31,37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131 }; 对于(i=0;i,c,floating-point,C,Floating Point,我不明白为什么我在这个程序中会遇到浮点异常错误。在循环的第二次迭代中,I是1,所以当你除以I-1时,你就是在除以0 如何解决这个问题取决于程序的目的。在循环的第二次迭代中,i是1,所以当你除以i-1时,你等于除以0 如何解决这个问题将取决于程序的用途。在第二次迭代时,i=1,因此除以0。在第二次迭代时,i=1,因此除以0。对于(i=0;i

我不明白为什么我在这个程序中会遇到浮点异常错误。

在循环的第二次迭代中,
I
是1,所以当你除以
I-1
时,你就是在除以0


如何解决这个问题取决于程序的目的。

在循环的第二次迭代中,
i
是1,所以当你除以
i-1
时,你等于除以0


如何解决这个问题将取决于程序的用途。

在第二次迭代时,i=1,因此除以0。

在第二次迭代时,i=1,因此除以0。

对于(i=0;i<30;i++){
#include <stdio.h>

int
main()
{
  int i;
  int c;
  int a[30] = { 5,  7,  11, 13,  17,  19,  23,  29,  31,  37,
                41, 43, 47, 53,  59,  61,  67,  71,  73,  79,
                83, 89, 97, 101, 103, 107, 109, 113, 127, 131 };
  for (i = 0; i < 30; i++) {
    c = (a[i] + i) / (i - 1);
    printf("Value of c is %d", c);
  }
}
c=(a[i]+i)/(i-1);
在这个循环的第二次迭代中,你除以零

由于历史原因,在Unix系统上,整数除以零是使用相同的信号(SIGFPE,“浮点异常”)报告的,该信号用于报告实际由浮点运算引起的错误。这一点现在无法更改,因为太多现有程序依赖它

(我不知道实际的历史原因是什么。它们可能与“PDP-11有一个浮点除法指令,但不是整数除法指令,所以最初的C编译器使用浮点数学来实现整数除法”类似,但我只是编出来的,如果是真的,那是偶然的。)

(讽刺的是,在现代CPU上,浮点除零通常会产生±Inf结果,但不会触发信号,除非使用
fesetenv
打开补漏白。)

for(i=0;i<30;i++){
c=(a[i]+i)/(i-1);
在这个循环的第二次迭代中,你除以零

由于历史原因,在Unix系统上,整数除以零是使用相同的信号(SIGFPE,“浮点异常”)报告的,该信号用于报告实际由浮点运算引起的错误。这一点现在无法更改,因为太多现有程序依赖它

(我不知道实际的历史原因是什么。它们可能与“PDP-11有一个浮点除法指令,但不是整数除法指令,所以最初的C编译器使用浮点数学来实现整数除法”类似,但我只是编出来的,如果是真的,那是偶然的。)


(具有讽刺意味的是,在现代CPU上,浮点除0通常会产生±Inf结果,但不会触发信号,除非使用
fesetenv
打开补漏白。)

大约只有在获得FPE(浮点异常)的时候,才有除法0具有讽刺意味的是,在现代C程序中,当你进行整数除零时,你的除法是0。具有讽刺意味的是,在现代C程序中,只有当你进行整数除零时,你才会得到FPE(浮点异常)。这解释了为什么会有异常,而不是为什么会有浮点异常(Unix的“SIGFPE”)。这解释了为什么会有异常,而不是为什么会有浮点异常(Unix的“SIGFPE”)。这解释了为什么会有异常,而不是为什么会有浮点异常(Unix的“SIGFPE”)。这解释了为什么会有异常,而不是为什么会有浮点异常(Unix的“SIGFPE”)。“历史原因”就像以前一样?通常的“一直都是这样,所以我们坚持下去也是错误的。”或者其他什么?只是好奇。@alk我不知道历史。我知道现在更改它将被视为ABI和API中断-您必须引入一个全新的信号号,因为没有其他更合适的了。
SIGFPE
的三参数信号处理程序可以使用
si_code
来说明实际发生了什么ned,但我不想在我的回答中提到这一点,因为我觉得这太离题了。@alk:我也不记得了,所以我贴了一个。我模糊地记得可能是硬件(英特尔?)这为所有算术异常生成了一个陷阱。但是为什么不将信号命名为
SIGARITH
或类似的名称,而不是
SIGFPE
?@EricPostpuschil谢谢,如果你得到一个好的答案,我将在这里进行总结。@zwol:现在可以将
SIGARITH
定义为与相同的值de>SIGFPE并更新各种文本消息以报告“算术异常”而不是“浮点异常,”例如,换言之,除了用于人类的文本外,对软件的工作方式不做任何更改。或者,我们可以将整数类型定义为指数范围为零到零的浮点类型的子集,从而使所有整数异常都成为浮点异常。“历史原因”与通常情况一样“一直都是这样,所以我们坚持下去也是错误的。"或者其他什么?只是好奇。@alk我不知道历史。我知道现在更改它将被视为ABI和API中断-您必须引入一个全新的信号号,因为没有其他更合适的了。
SIGFPE
的三参数信号处理程序可以使用
si_code
来说明实际发生了什么ned,但我不想在我的回答中提到这一点,因为我觉得这太离题了。@alk:我也不记得了,所以我贴了一个。我模糊地记得可能是硬件(英特尔?)这为所有算术异常生成了一个陷阱。但为什么不将信号命名为
SIGARITH
或类似的名称,而不是
SIGFPE
?@ericpostpishil谢谢,如果你
for(i = 0; i < 30; i++){
    c = (a[i] + i)/(i-1);