2011-11-04 89 views
2

我在大学学习C,而我是编程新手。我的任务是创建一个函数,它应该为我的输入计算一个弧线。递归调用函数时出现分段错误

我试图用xcode进行调试。一切正常,直到返回arcsin(新);叫做。那么它的一个分段错误:11。我不知道为什么,但浮点的断点arcsin(floatvalue){...在运行第二个循环时告诉我浮动值和浮点值是NAN。

float arcsin(float value){ 

float old = value; 
float new = value + (0.5 * ((value * value * value)/3)); 
float accurate = 0.00001; 

    if ((new - old) < accurate){ 
    return new; 
    } 

    else{ 
    return arcsin(new); 
    } 
} 


int function_arcsin(int sigdig, float value){ 

    value = arcsin(value); 
    printf("%.10e\n",value); 

return 0; 
} 
+0

新是一个保留关键字。叫它像float newval – spicavigo

+2

@spicavigo:这是C,而不是C++,所以没关系。 – bitmask

+0

@spicavigo不是普通的C. –

回答

2

当调用堆栈变得太大 - 即递归级别太多时,会发生seg错误。

就你而言,这意味着条件(new - old) < accurate将始终评估为假 - 也许并不总是,但足够的时间膨胀调用堆栈。

测试你的代码我发现new(可能不是一个好的变量名称选择)一直在增长,直到超过float的极限。你的算法可能是错误的。

+0

'new'这个名字也让我想起了一秒钟,因为它是C++中的一个关键字,但是这真的算作C中一个不好的选择吗? (我现在不熟悉C风格的规则)。 – Steve314

+1

@ Steve314你永远不知道什么时候你想要将代码移植或包含到C++中,现在不妨选择好,而不是稍后重构,对吗? –

+1

@ Steve314这种无意义的变量名称作为'new'或'old'应该在任何语言中都被认为是不好的选择 –

0

我很确定分段错误是由太深的递归引起的。虽然许多编译器可以将很多递归代码优化为迭代代码,但有些编译器却不行,而且这很常见。调试选项来禁用它。

转换为迭代形式将停止段错误 - 但是,除非我错过我的猜测,否则请给出无限循环。我不希望工作递归解决方案成为一个问题在这里,除非你正在测试超出范围的近似值收敛 - 在这种情况下,我的第一个猜测是输入范围-pi到+ pi应该可以用于任何可用的近似弧线。

我并不熟悉arcsin的迭代逼近,而我的google-fu还没有找到答案,但我怀疑你在float new = ...行中的计算错了。

我发现这个链接...

http://mathforum.org/library/drmath/view/54319.html

这不是有益的 - 你的代码是不是暗示描述这两种方法的。

0

我测试你的程序,看到永远不会结束循环:

((new - old) < accurate) // never is true 

,如果你用数字> 0尝试,在10次迭代达到楠。用数字< 0,继续数千次,并导致太深的递归。

相关问题