C语言递归实现二分法求函数根触发segmentation fault问题求助
递归失败及段错误原因
你遇到的段错误不是内存越界写入,是栈溢出,核心原因有两点:
- 你使用的
float类型精度不足:float是IEEE754单精度浮点数,仅能提供约6~7位十进制有效数字的精度,你传入的delta是0.00000000002(即2e-11),已经远超过float的精度极限,fabs(func(mean)) < delta的终止条件永远无法满足,递归会一直执行。 - 当区间
[a,b]的长度小到float无法再细分时,计算得到的mean会和a或b完全相等,后续递归的区间不会再缩小,进入无限递归,递归深度持续增加。而程序栈的空间是有限的(通常只有几MB),当递归深度超过栈的承载上限时,就会触发栈溢出,抛出segmentation fault:11错误。
你运行输出里delta打印为0.000000也验证了float无法表示这么小的数值,已经被截断为接近0的值。
负零的含义
你输出里的-0.000000就是负零,是IEEE754浮点数标准中的特殊值:符号位为1,阶码和尾数全为0。
数值上负零和正零完全相等,仅符号位有区别,通常出现在极小的负浮点数下溢、负数除以正无穷等运算场景。你的代码里出现负零是因为func(a)*func(mean)是一个极小的负数,小于float能表示的最小非负正常值,触发下溢被表示为负零。
修复方案
- 把代码中所有的
float替换为double,双精度浮点数有约15~16位十进制有效数字,可以满足你设置的2e-11精度要求。 - 如果继续使用float,delta不要设置到小于
1e-6,超过float精度的阈值没有实际意义。 - 也可以把递归版本的二分法改为迭代实现,从根本上避免栈溢出风险。
内容的提问来源于stack exchange,提问作者user305883
相关产品推荐
相关产品推荐

