c - 为什么在调用 realloc() 后,模运算会出现浮点异常?
问题描述
我写了这段代码来找到第x个最大的素数:
for (int i = 3 /* 2 has already been added to the list */; i < maxNumber; i += 2) {
for (int tested = 0; ; tested++) {
if (primes[tested] == 0) {
break;
}
if (i % (int) primes[tested] == 0) {
goto loop;
}
}
count++;
if (count == primesSize) {
primesSize += 2000;
primes = (double*) realloc(primes, sizeof(double) * primesSize);
}
primes[count - 1] = i;
printf("Prime number #%d: %d\n", count, i);
printf("Prime size: %d\n", primesSize);
loop: /* statement that does nothing */ if (1) {}
}
但是,当使用大数字(> 8,000)时,它返回了“浮点异常”。
什么时候发生在这里:
- 用户选择一个数字。
maxNumber
设置为所选数字的平方根。1000 * sizeof(double)
首先,分配一个大小为的双指针。它存储在primes
变量中。- 如果发现一个数是素数,则将其添加到由指针表示的数组中。
- 当第 1,000 个数字被添加到数组中时,
primes
指针被重新分配以存储 2,000 个以上的数字。
- 当第 1,000 个数字被添加到数组中时,
当我过去gdb
查找错误原因时,我发现这部分是问题的原因:
for (int tested = 0; ; tested++) {
if (primes[tested] == 0) {
break;
}
if (i % (int) primes[tested] == 0 /* breaks here */) {
goto loop;
}
}
更新:我认为第一个if
语句会解决这个问题,因为printf("%f", primes[tested])
打印 0。但是,它没有,并且“中断”没有执行。
当代码中断时,tested
是 1001。我转换primes[tested]
为整数,因为我使用的模算术运算需要整数才能工作。primes[tested]
但是,当我从代码打印时,它显示0。如果我从 gdb 打印值,我会得到6.1501785659964211e-319。
我错过了什么?我应该修改我的调用realloc
以避免此异常吗?
解决方案
我认为第一个
if
语句会解决这个问题,因为printf("%f", primes[tested])
打印 0。但是,它没有,并且“中断”没有执行。
您测试是否primes[tested] == 0
,但您的代码仅在((int)primes[tested]) == 0
. 这些根本不是一回事。此外,primes[tested]
使用格式打印的值%f
并不能可靠地告诉您不同,因为它只给您小数点后的 6 位数字。改为尝试一种"%e"
格式,并测试您实际需要的条件,而不是相关的、较弱的条件。
但更好的是,这里不要使用浮点类型。FP 没有用于离散数学问题的业务,例如您似乎试图解决的问题。如果primes[tested]
实际上包含素数或可能素数,则unsigned long long int
可能具有与 相同的大小double
,并且几乎可以肯定可以准确地表示更广泛的素数。或者如果它只包含标志,例如在素数筛中,那么任何比它更宽的东西char
都是浪费的。
推荐阅读
- python - 如何检查 PDB 中当前调试函数的返回值?
- asp.net-core - 如何在 ASP.NET Core 中编写 Request.ServerVariables["HTTP_X_FORWARDED_FOR"]?
- android - 错误:合并两个分支后找不到符号类 DataBindingComponet
- visual-studio-code - 如何在 VS Code 中配置换行缩进大小?
- android - Android 一次性设备 (COSU) 重启后无法进入 lockTaskMode
- html - IE 10 海报图像被视频标签中的源覆盖
- java - 如何在方法中模拟 this.method()?
- asp.net - web.config 中的 ip 范围模式
- javascript - 如何将 YAML 文件转换为 Dockerfile
- c++ - 从函数 BY VALUE 返回一个数组,当你返回一个结构时会发生什么?