64位整数质因数分解程序输入13位数值时异常退出问题排查
核心问题定位
- 返回值溢出导致循环提前终止
你定义的ReadInput函数返回值为32位int类型(VS默认int为32位,最大值仅为2147483647,共10位),但实际返回的是64位的输入数值。当输入13位数值时,返回值发生截断溢出,最终返回结果≤0,直接导致while (ReadInput(&n, &ret) > 0)的循环条件不成立,程序无报错直接退出,这是你遇到问题的根因。 - VS环境格式符不兼容
Windows VS下int64_t对应的标准输入输出格式符为%I64d,你使用的%lld是类Unix系统下的格式符,存在兼容性风险。 - 循环变量溢出隐患
质因数分解逻辑中的循环变量i为32位int类型,当输入数值的平方根超过int最大值时,会触发溢出导致逻辑异常。 - sqrt精度隐患
sqrt默认处理double类型,仅能精确表示≤2^53的整数,当输入更大的64位整数时,平方根计算会出现精度误差。
修复后完整代码
#include<stdio.h> #include<math.h> #include<stdbool.h> #include<stdint.h> int64_t ReadInput(int64_t *n, int *ret); void Primal_Factorization(int64_t n); enum {INPUT_ERROR = 100, SUCCESS = 0}; int main() { int ret = SUCCESS; int64_t n = 0; while (ReadInput(&n, &ret) > 0) { Primal_Factorization(n); } if (n < 0) { fprintf(stderr, "Error: Chybny vstup!\n"); ret = INPUT_ERROR; } return ret; } int64_t ReadInput(int64_t *n, int *ret){ if(scanf("%I64d", n) != 1){ *n = 0; fprintf(stderr, "Error: Chybny vstup!\n"); *ret = INPUT_ERROR; } return *n; } void Primal_Factorization(int64_t n){ int64_t n_sqrt = (int64_t)sqrt(n); // 修正sqrt精度误差,确保n_sqrt是不小于实际平方根的最小整数 while ((n_sqrt + 1) * (n_sqrt + 1) <= n) n_sqrt++; while (n_sqrt * n_sqrt > n) n_sqrt--; int count; int64_t n_origin = n; bool first_iteration = true; printf("Prvociselny rozklad cisla %I64d je:\n", n); for (int64_t i = 2; i <= n_sqrt; i++){ count = 0; if(n % i == 0){ if(!first_iteration) printf(" x "); while (n % i == 0){ n = n / i; count++; } if(count != 1) printf("%I64d^%d", i, count); else printf("%I64d", i); first_iteration = false; // 分解后更新平方根,提升运行效率 n_sqrt = (int64_t)sqrt(n); while ((n_sqrt + 1) * (n_sqrt + 1) <= n) n_sqrt++; while (n_sqrt * n_sqrt > n) n_sqrt--; } } if(n_origin == n) printf("%I64d\n", n); else if(n != 1) printf(" x %I64d\n", n); else printf("\n"); }
验证说明
修改后输入13位数值如1000000000000,可正常输出分解结果:Prvociselny rozklad cisla 1000000000000 je: 2^12 x 5^12。
内容的提问来源于stack exchange,提问作者Angra Mainyu
相关产品推荐
相关产品推荐

