Ошибка сегментации при рекурсивном вызове функции - PullRequest
2 голосов
/ 04 ноября 2011

Я изучаю C в моем колледже, и я новичок в программировании. Моя задача - создать функцию, которая будет вычислять арксинус для моего ввода.

Я попытался отладить его с помощью xcode. Все работает нормально, пока не вернется arcsin (новый); называется. Тогда это ошибка сегментации: 11. Я не уверен почему, но точка останова на float arcsin (floatvalue) {... при выполнении второго цикла говорит мне, что float old и значение с плавающей точкой 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;
}

Ответы [ 3 ]

3 голосов
/ 04 ноября 2011

Ошибка сегмента возникает, когда стек вызовов становится слишком большим - то есть слишком много уровней рекурсии.

В вашем случае это означает, что условие (new - old) < accurate всегда будет оцениваться как ложное - ну, возможно, не всегда, но достаточно раз, чтобы раздуть стек вызовов.

Тестирование вашего кода Я вижу, что new (вероятно, не лучший выбор имени переменной) продолжает расти, пока не превысит пределы float.Ваш алгоритм, вероятно, неверен.

0 голосов
/ 04 ноября 2011

Я протестировал вашу программу и увидел, что цикл никогда не заканчивается:

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

если вы попробуете с числами> 0, достигнет nan за 10 итераций. С числами <0 продолжайте тысячи раз и вызывает слишком глубокую рекурсию. </p>

0 голосов
/ 04 ноября 2011

Я почти уверен, что ошибка сегментации вызвана слишком глубокой рекурсией.Хотя многие компиляторы могут оптимизировать много рекурсивного кода в итеративный код, некоторые не могут, и это довольно часто встречается, например, в параметрах отладки, чтобы отключить это.

Преобразование в итеративную форму остановит segfault - но, если толькоЯ скучаю по своему предположению, вместо этого дать бесконечный цикл.Я не ожидал бы, что работающее рекурсивное решение будет проблемой здесь, если только вы не тестировали со значениями вне диапазона, с которым сходится аппроксимация - в этом случае, я предполагаю, что входные данные в диапазоне -пи к + пи должно быть в порядке для любого пригодного приближения арксинуса.

Я не знаком с итеративным приближением арксинуса, и мой гугл-фу еще не нашел ответ, но я подозреваю, что у вас естьнеправильный расчет в строке float new = ....

Я нашел эту ссылку ...

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

Это не так полезно - ваш код не наводит на мысль оописан любой подход.

...