Как рассчитать логарифм (основание N) для bigInt? - PullRequest
0 голосов
/ 14 мая 2018

Вопрос - Как рассчитать логарифм для bigInt? :

Я использую эту библиотеку bigInt: https://www.npmjs.com/package/big-integer для некоторых вычислений.


let myBigInt = bigInt(20).pow(200) // gets 160693804425899027554196209234116260252220299378279283530137600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Теперь я хотел бы применить логарифм к переменной с типом bigInt, но в документах я не смог найти ни одного соответствующего вызова функции для реализованного функция логарифма как (с использованием маленьких целых) нативный вызов js Math.log.


Мой вопрос : Как реализовать функцию log(baseN, valueX) для библиотеки bigInt?


Примечание: let myLogarithm = myBigInt.log(baseN) не является допустимой реализацией.

1 Ответ

0 голосов
/ 14 мая 2018

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


Посмотрите wikipedia , как я это сделал, потому что есть очень хорошая статья о baseConversion.

Ниже вы можете найти функцию для Math.log(base, value), которая может вычислять log(base) из значения.

Math.log = (function() {
  var log = Math.log;
  return function(base, n) {
    return log(n)/(base ? log(base) : 1);
  };
})();

Чтобы вычислить logarithmToBaseN для значений bigInt, просто используйте эту строку кода:

let logarithmToBaseN = (myBigInt.toString().length * Math.log(baseN, 10) + Math.log(baseN, parseFloat("0." + myBigInt))) - 1);

Редактировать : Это решение представляет собой крошечный обходной путь bacause parseFloat("0." + myBigInt), преобразующий большое значение, например 100000, в действительно маленькое значение, например 0.100000,..., что приводит к тому, что оно будет иметь целочисленную точность.


Согласно комментарию @Jonas W : Решение очень точное для нижних оснований, таких как (5, 10, ...), в сочетании с низкими значениями, такими как 10, 1000, 100000 - но для действительно большихзначения как bigInt(20).pow(200) это не так.

Примечание : использование parseFloat ( IEEE 754 двойной точности с плавающей точкой) означает, что у вас есть максимум 52 бит точности , что составляет чуть более 15 десятичных знаков.После этого - точность будет убита.

Примечание: Для действительно больших значений bigInt(20).pow(200) в сочетании с действительно большими базами , например, 100 * (и более), это снова кажется довольно точным.

Привет, Джонас.

...