除零错误外触发浮点异常的场景有哪些?附Luhn算法代码报错案例
问题解答
代码触发异常的直接原因
你代码中出现了预期外的除零操作,根源是对C语言运算符的误用:C语言里^是按位异或运算符,不是幂运算符。当循环中x累加到等于10时,10 ^ x的计算结果为0,a / (10^x)等价于整数除零,而多数系统会将整数除零的错误归类到SIGFPE(浮点异常信号)中上报,哪怕你没有用到浮点运算。
另外你的代码还有多处逻辑问题会导致Luhn校验逻辑失效:
int类型无法存储13-19位的信用卡号,会发生整数溢出- 缺少必须的头文件:使用
bool需要引入<stdbool.h>,使用get_int需要引入CS50的<cs50.h> - 按位异或的逻辑完全不符合你预期的“10的x次方”计算需求,会导致取数位的逻辑全部错误
除零错误外触发浮点异常的常见场景
浮点异常(SIGFPE)的实际覆盖范围远大于字面意义的“浮点运算错误”,除零之外的触发场景包括:
- 浮点数上溢:运算结果超过当前浮点类型可表示的最大值
- 浮点数下溢:运算结果小于当前浮点类型可表示的最小正规格化数
- 无效浮点操作:比如对负数开平方、计算
0/0、无穷大加减无穷大、无穷大除以无穷大等非法运算 - 整数溢出:部分架构下开启对应检测开关后,整数运算溢出也会触发SIGFPE
- 精度不精确告警:部分架构开启对应异常位后,浮点运算结果无法被精确表示时也会触发异常
代码修正建议
你可以参考以下修改方向调整代码:
- 用字符串或者
long long类型存储信用卡号,避免整数溢出 - 自己实现10的幂次计算,不要误用
^运算符 - 调整取数位的逻辑,符合Luhn算法从右往左数的规则
#include <stdio.h> #include <stdbool.h> // 如果使用CS50的get_long_long需要取消下一行注释 // #include <cs50.h> long long power10(int n) { long long res = 1; for(int i=0; i<n; i++) res *=10; return res; } int main(void) { // 用long long存储卡号,避免溢出 long long a; printf("enter your card number:"); scanf("%lld", &a); // 如果用CS50库可以替换为:long long a = get_long_long("enter your card number:"); int x = 1; int y = 0; int s = 0; bool checksum; while (a / power10(x) > 0) { long long c = a / power10(x); int z = c % 10; int k = 2 * z; int d = (k / 10) + (k % 10); y += d; x += 2; } x = 0; while (a / power10(x) > 0) { long long l = a / power10(x); int m = l % 10; s += m; x += 2; } int g = s + y; if(g % 10 == 0) { checksum = true; printf("valid\n"); } else { checksum = false; printf("invalid\n"); } return 0; }
内容的提问来源于stack exchange,提问作者dxuian
相关产品推荐
相关产品推荐

