对信用卡号做增量除以10时为何反复出现Floating point exception错误?
解决信用卡号增量除以10时的浮点异常问题
问题根源
你遇到的Floating point exception (core dumped)核心原因是整数除以0,同时代码里还有几个明显的逻辑和语法错误:
- 当
i=0时,10*i结果为0,执行cc/n就是除以0,直接触发浮点异常。 - 多处出现未定义变量
a(比如printf("%i\n",a);),这属于语法错误,编译阶段就该报错。 - 用
pow()计算10的幂:pow()返回浮点型,强制转long可能出现精度偏差(比如pow(10,3)可能返回999.999999,转成long后变成999而非1000)。 - 循环嵌套逻辑混乱:外层for和内层do-while都在递增
i,导致循环逻辑失控,变量值超出预期。
正确实现代码
要实现信用卡号每次增量除以10的操作,不用嵌套循环,也没必要用pow(),直接维护一个除数变量逐步乘10即可,同时完全避免除以0的情况:
#include <stdio.h> #include <cs50.h> int main(void) { // 用get_long拿卡号,避免int范围不够的问题 long cc = get_long("CC:\n"); // 初始除数为1,第一次除以1就是原卡号,之后每次乘10 long divisor = 1; // 循环4次,依次输出除以10、100、1000、10000的结果 for (int i = 0; i < 4; i++) { long d = cc / divisor; printf("%li\n", d); // 除数乘10,为下一次除以10的更高次幂做准备 divisor *= 10; } }
关键改进说明
- 换用
get_long():信用卡号一般是13-19位,远超过int的存储范围(通常是-231到231-1),用long存储更稳妥。 - 避免除以0:初始除数设为1,每次循环乘10,保证除数始终是10的正整数次幂,不会出现0。
- 抛弃
pow():用整数乘法维护除数,彻底避免浮点精度带来的误差。 - 修正输出:用定义好的
d替代未定义的a,同时用%li作为long类型的格式化输出符,避免类型不匹配导致的乱码。
之前修改的问题点
你之前的几个修改版本都有问题:
long decimal = cc/(10 * i);:i=0时触发除以0;i=1时除以10,i=2时除以20,这不是你要的“每次除以10的增量操作”(应该是除以10、100、1000...)。- 混用
%i、%li、%f输出:%i对应int,%li对应long,%f对应浮点型,类型不匹配会导致输出结果混乱。
内容的提问来源于stack exchange,提问作者mkstar
相关产品推荐
相关产品推荐

