2017-02-22 122 views
0

Я хочу вычислить некоторый (C/D) -ый корень (A/B) с произвольной точностью для десятичного расширения корня (например, если желаемая точность является целым числом E, результат должен содержать E цифры после десятичной точки из корня E может быть равно, по меньшей мере, десяткам тысяч, A, B, C, D - целые числа, содержащие десятки тысяч десятичных цифр), но все найденные мной математические библиотеки Javascript откажутся чтобы справиться с такими цифрами.
Я попытался использовать Decimal.js, но имеет ограниченную точность и ограниченный размер ввода. Например, если я хочу, чтобы вычислить квадратный корень из 2 с 1025 значащими цифрами (где последняя цифра может быть округлена как-то), я использовал следующий код для Decimal.js:Как вычислить (C/D) -ый корень (A/B) с произвольной точностью для сколь угодно больших целых чисел A, B, C и D?

Decimal.set({ precision: 1025 }); 
var r2 = Decimal.pow(2, Decimal.div(1, 2)).toDP(1025).toString(); 
console.log(r2); 

, но я получаю

Error: [DecimalError] Precision limit exceeded 

Возможно ли решить проблему с использованием клиентской стороны (работающей в браузере) Javascript? Насколько я знаю, есть некоторые эффективные алгоритмы для вычисления корней даже для миллионов цифр цифр, но я не видел ни одного из них, реализованного в JS для сколь угодно больших чисел и произвольной точности. Это вообще возможно?

+0

'Точность: 1025': -o – Rajesh

+0

Вы можете установить внутреннюю рабочую точность выше отображаемой точности, 1 цифра каждые 2 или 3 операции в расчетной цепи плюс буфер 3. Это даст здесь 'Decimal.set ({precision: 1029});' – LutzL

+0

@LutzL: Я не понимаю ... какой код я должен использовать, чтобы получить, скажем, 1500 цифр квадратного корня из двух в Decimal.js? Более того, насколько я понимаю, Decimal.js не может иметь дело с целыми числами больше 2^1024. –

ответ

0

в decimal.js, Установка precision до 1025 дает вам десятичные цифры 1025 (мантиссы) в количестве.

.toDP(1025) относится к цифрам после десятичных точек или десятичных знаков, что требует в этом примере всего 1026 знаков мантиссы, так как перед десятичной точкой имеется одна цифра 1.

Можно предположить, что методы используют должным образом повышенную внутреннюю рабочую точность, так что выход является правильным относительно округления. Это означает, что последняя цифра может быть не такой, если ее пересчитать с большей точностью. Установите для режима округления значение round-down (в направлении нуля), если вы хотите это предотвратить.


Причина, что способ питания терпит неудачу с точностью, превышающей 1020 является то, что внутренняя точность превышает 1025, который является длиной внутренней LN10 постоянная заданной в виде строки. Ошибка связана с явным тестом против этой ситуации.

Возможно, для этой библиотеки вы можете использовать результат 1000 цифр в качестве начальной точки для получения улучшенных результатов методом Newton.

my_div = document.getElementById("my_div") 
 
Decimal.set({precision:1010}); 
 
var a = Decimal.pow(new Decimal(2), Decimal.div(1,2)) 
 
my_div.innerHTML += "initial pr=1000 : "+a.toDP(1000); 
 
Decimal.set({precision:2500}); 
 
for(var k=1; k<=4; k++) { 
 
    a = Decimal.div(a.add(Decimal.div(2,a)),2); 
 
    my_div.innerHTML += "<br> Newton "+k+" : "+a; 
 
}
<script src="https://raw.githubusercontent.com/MikeMcl/decimal.js/master/decimal.js"></script> 
 
<div id="my_div"></div>

+0

И как я могу использовать Decimal.js, чтобы увидеть первые 1500 десятичных цифр после десятичной точки sqrt (2)? Неважно, какую точность я выбираю, но я всегда получаю сообщение об ошибке примерно за 1000 знаков. Более того, как я могу иметь дело с цифрами больше 2^1024? Например, попытка использовать 'new Decimal ('0b1 ...')' с более чем 1024 двоичными цифрами приведет к ошибке. –

+0

Вы не можете использовать функцию мощности (и, возможно, также exp и log) с точностью больше 1020, потому что их код содержит константу 'LN10', которая« только »содержит 1025 цифр. Вы можете использовать Newton для уточнения полиномиальных корней, см. Последнее редактирование и пример. – LutzL

+0

Насколько я понимаю, этот метод основан на знании производных степеней. Я не думаю, что это можно применить к большим числам, используя decimal.js. –