Просто чтобы почувствовать это, для вашего диапазона y = 50, x = 0 дает r = 50, а y = 50, x = +/- 30 дает r ~ = 58.3. Вы хотите хорошее приближение для +/- 0,1% или +/- 0,05 абсолютного значения. Точность намного ниже, чем у большинства библиотек.
Два приблизительных подхода - вы вычисляете r на основе интерполяции из предыдущего значения или используете несколько членов подходящего ряда.
Интерполяция от предыдущего r
r = (x 2 + y 2 ) 1/2
др / дх = 1/2. 2х. (x 2 + y 2 ) -1 / 2 = x / r
double r = 50;
for ( int x = 0; x <= 30; ++x ) {
double r_true = Math.sqrt ( 50*50 + x*x );
System.out.printf ( "x: %d r_true: %f r_approx: %f error: %f%%\n", x, r, r_true, 100 * Math.abs ( r_true - r ) / r );
r = r + ( x + 0.5 ) / r;
}
Дает:
x: 0 r_true: 50.000000 r_approx: 50.000000 error: 0.000000%
x: 1 r_true: 50.010000 r_approx: 50.009999 error: 0.000002%
....
x: 29 r_true: 57.825065 r_approx: 57.801384 error: 0.040953%
x: 30 r_true: 58.335225 r_approx: 58.309519 error: 0.044065%
, что, кажется, соответствует требованию ошибки 0,1%, поэтому я не стал кодировать следующий, так как для этого потребовалось бы немного больше шагов вычисления.
Усеченная серия
Ряд Тейлора для sqrt (1 + x) для x около нуля равен
sqrt (1 + x) = 1 + 1/2 x - 1/8 x 2 ... + (- 1/2) n + 1 x п
Используя r = y sqrt (1 + (x / y) 2 ), вы ищете термин t = (- 1/2) n + 1 0.36 n с магнитудой меньше 0,001, log (0,002)> n log (0,18) или n> 3,6, поэтому принятие условий для x ^ 4 должно быть в порядке.