C语言实现种群增长计算时对数输出0或极值异常,排查变量类型适配问题
种群增长代码异常排查与修正方案
核心问题定位
- 整数除法截断 是触发异常值的根本原因
你代码中double a = Y/X;、double b = 1+(X/1200);的写法存在整数运算截断问题:X和Y为int类型,C语言中两个整数做除法会直接丢弃小数部分取整。例如初始种群为100时,X/1200的整数计算结果为0,对应底数b=1.0,此时log(1.0)=0,分母为0的除法运算会触发未定义行为,直接输出0、极端随机负数(你看到的-9223372036854775808即整数类型越界的默认输出)这类异常值。
核心修正点
- 修正类型转换:在除法运算前对整数操作数做强制浮点数转换,避免截断:
- 种群倍数a的计算:
double a = (double)Y / X; - 增长底数b的计算:
double b = 1 + (double)X / 1200;
修正后X=100时,b的计算结果为1 + 100.0/1200 ≈1.0833,与你预期的对数底数完全匹配,代入测试用例可算出8.66年的原始结果。
- 种群倍数a的计算:
- 编译注意事项:C语言math库不属于默认链接范围,修正代码后若编译报log函数未定义的错误,需要在编译命令中追加
-lm参数显式链接数学库。 - 取整逻辑补全:原始计算值为小数年数,可通过math库的
ceil()函数实现向上取整,直接得到符合要求的整年数结果(测试用例8.66年经取整为9年)。
修正后可运行代码
#include <cs50.h> #include <stdio.h> #include <math.h> double log_a_to_base_b(double a, double b) { return log(a) / log(b); } int main(void) { // 输入初始种群规模 int X; do { X = get_int("How many llamas do you start with? \n"); } while (X < 1); // 输入目标种群规模 int Y; do { Y = get_int("How many llamas do you have after a certain period of time? \n"); } while (Y < 1 || Y < X); // 强制浮点数转换,规避整数除法截断问题 double a = (double)Y / X; double b = 1 + (double)X / 1200; double raw_years = log_a_to_base_b(a, b); int final_years = ceil(raw_years); // 向上取整得到整年数 printf("Start size : %i \n", X); printf("End size : %i \n", Y); printf("Required years: %i \n", final_years); return 0; }
内容的提问来源于stack exchange,提问作者Dylan
相关产品推荐
相关产品推荐

