Ваша программа имеет неопределенное поведение, так как и new_guess
и old_guess
неинициализируются при вводе цикла.
Неверное условие: вы должны остановиться, когда new_guess == old_guess
или после разумного максимального количества итераций.
Вот модифицированная версия:
#include <math.h>
#include <stdio.h>
int main(void) {
double n, x;
int i;
printf("Enter numbers:");
while (scanf("%lf", &n) == 1 && n >= 0.0) {
x = 1.0;
/* Using a while loop as per the assignment...
* a for loop would be much less error prone.
*/
i = 0;
while (i < 1024) {
double new_guess = (x + (n/x))/2.0;
if (new_guess == x)
break;
x = new_guess;
i++;
}
printf("%g: %.17g, %d iterations, diff=%.17g\n",
n, x, i, sqrt(n) - x);
}
return 0;
}
Учитывая начальное значение, число итераций возрастает с размером n
, превышающей 500 для очень больших количествах, но обычно меньше, чем 10 для небольших чисел. Также обратите внимание, что этот алгоритм не работает для n = 0.0
.
Вот несколько более сложный метод, с использованием разложения с плавающей точкой и объединения функций double frexp(double value, int *exp);
и double ldexp(double x, int exp);
. Эти функции не выполняют никаких вычислений, но дают гораздо лучшую начальную точку, достигая завершения в 4 или 5 итераций для большинства значений:
#include <math.h>
#include <stdio.h>
int main(void) {
double n, x;
int i, exp;
printf("Enter a number:");
while (scanf("%lf", &n) == 1 && n >= 0.0) {
if (n == 0) {
x = 0.0;
i = 0;
} else {
frexp(n, &exp);
x = ldexp(1.0, exp/2);
for (i = 0; i < 1024; i++) {
double new_guess = (x + (n/x))/2.0;
if (new_guess == x)
break;
x = new_guess;
}
}
printf("%g: %.17g, %d iterations, diff=%.17g\n",
n, x, i, sqrt(n) - x);
}
return 0;
}
но большинство ваших переменных не инициализировано или не используется ??? –
Я знаю и вот почему я потерял. Должен ли я сделать old_guess = n/2? – billnye852
После scanf поместите это: 'old_guess = n/2;' –