声明s1为int时153的水仙花数验证失效,改为double正常,求解释
问题原因分析
核心问题出在**pow()函数的浮点精度误差**以及整数类型的截断特性上:
pow()是C标准库中的浮点运算函数,返回值为double类型。由于浮点数二进制存储的局限性,计算整数立方时可能出现微小精度偏差。比如计算5^3时,pow(5,3)实际返回的可能不是精确的125.0,而是124.99999999999999这类接近125但略小的值。- 当把这个浮点值赋值给
int类型的s1时,C语言会直接截断小数部分,只保留整数位。原本应加125的地方实际加了124,导致153的各位立方和变为1 + 124 + 27 = 152,无法与原数153匹配。 - 370、371、407这几个数的
pow()计算误差方向刚好是向上的,或者误差小到截断后仍等于正确整数(比如pow(7,3)可能返回343.00000000000006,截断后还是343),所以验证不受影响。
当s1声明为double类型时,即使存在微小精度误差,整数i会被隐式转换为double,误差范围小到足以让两者判定为相等。
修复方案
直接用整数乘法替代pow(),彻底避免浮点精度问题:
int s1; for(int i=140; i<=500; i++){ int tmp=i; s1=0; while(tmp!=0){ int digit = tmp % 10; s1 += digit * digit * digit; // 整数乘法计算立方 tmp = tmp / 10; } printf("i=%d s=%d ", i, s1); if(s1==i) printf("%d is cubic\n", i); else printf("\n"); }
内容的提问来源于stack exchange,提问作者redone_l
相关产品推荐
相关产品推荐

