Произвольная точность и численный анализ

1 min


Доступ к произвольной арифметике точности не обязательно устраняет трудности численного расчета. Вам все еще нужно знать, что вы делаете.

Прежде чем расширять точность, вы должны знать, как далеко ее расширить. Если вы недостаточно расширили его, ваши ответы не будут достаточно точными. Если вы расширяете его слишком далеко, вы тратите ресурсы впустую. Возможно, вы в порядке, тратите ресурсы, поэтому вы повышаете точность больше, чем необходимо. Но как далеко больше, чем необходимо?

В качестве примера рассмотрим проблему нахождения значений N такой что загар (N)> N обсуждается пару дней назад, После написания этого поста кто-то указал, что эти ценности N являются одной из последовательностей на OEIS, Одним из значений на сайте OEIS является

К = 1428599129020608582548671.

Давайте проверим этот загар (К)> К, Мы будем использовать нашего старого друга до н.э потому что он поддерживает произвольную точность. наш К это 25-значное число, поэтому давайте скажем bc, что мы хотим работать с 30 десятичными разрядами, чтобы дать себе немного места. (bc автоматически дает вам немного больше места, чем вы просите, но мы попросим еще больше.)

bc не имеет касательной функции, но имеет s() для синуса и c() для косинуса, поэтому мы будем вычислять касательную как синус над косинусом.

    $ bc -l
    scale = 30
    k = 1428599129020608582548671
    s(k)/c(k) - k

Мы ожидаем, что это вернет положительное значение, но вместо этого оно возвращает

-1428599362980017942210629.31…

Так что же, OEIS не так? Или есть bc игнорируя наш scale стоимость? Оказывается ни то, ни другое.

Вы не можете напрямую вычислить касательную большого числа. Вы используете уменьшение диапазона, чтобы свести его к проблеме вычисления тангенса небольшого угла, где будут работать ваши алгоритмы. Поскольку касательная имеет период π, мы уменьшаем К мод π с помощью вычислений К – ⌊К/ Π⌋π. То есть мы вычитаем столько кратных числа π, сколько можем, пока не получим число от 0 до π. Возвращаясь к bcмы вычисляем

    pi = 4*a(1)
    k/pi

Это возвращает

    454737226160812402842656.500000507033221370444866152761

и поэтому мы вычисляем тангенс

    t = 0.500000507033221370444866152761*pi
      = 1.570797919686740002588270178941

поскольку T немного больше, чем π / 2, касательная будет отрицательной. Мы не можем загореть (T) лучше чем К потому что загар (T) даже не больше 0. Итак, где все сломалось?

Расчет pi был точен до 30 значимых цифр, а расчет k/pi был точным до 30 значимых цифр, учитывая нашу ценность pi, До сих пор выполнил, как и обещал.

Расчетное значение k/pi правильно до 29 значащих цифр, 23 до десятичного знака и 6 после. Поэтому, когда мы принимаем дробную часть, у нас есть только шесть значащих цифр, и этого недостаточно. Вот где все идет не так. Мы получаем значение ⌊К/ π⌋ больше 0,5 в седьмом знаке после запятой, в то время как точное значение меньше 0,5 в десятичном знаке. Нам нужно было 25 – 6 = 19 более значимых цифр.

Это основная трудность вычисления с плавающей запятой: вычитание почти равных чисел теряет точность. Если два числа согласны с м десятичные разряды, вы можете ожидать потерять м значимые цифры в вычитании. Ошибка в вычитании будет мала по отношению к входным данным, но не мала по отношению к результату.

Обратите внимание, что мы вычислили k/pi до 29 значимых цифр, и с учетом этого результата мы вычислили дробную часть именно так, Мы точно рассчитали ⌊К/ π⌋π, но потеряли точность, когда мы вычислили, мы вычли это значение из К,

Наша ошибка в вычислениях К – ⌊К/ π⌋π был маленьким относительно К, но не относительно конечного результата. наш К порядка 1025и ошибка в нашем вычитании порядка 10-7, но результат порядка 1. Там нет ошибки в bc, Он выполнял каждый расчет с заявленной точностью, но ему не хватало рабочей точности, чтобы получить нужный нам результат.

Похожие сообщения


0 Comments

Ваш e-mail не будет опубликован. Обязательные поля помечены *