Использование Math.exp () в Javascript с BigDecimal для больших чисел с плавающей запятой - PullRequest
3 голосов
/ 20 сентября 2011

Я пытаюсь выполнить следующие вычисления в Javascript:

e^x / (1 + e^x)

, где x - длинное число с плавающей запятой.

В этом случае мне требуется точность вкак минимум 10-е десятичное место.

Я использовал BigDecimal для точной обработки чисел с плавающей запятой, как указано в Руководство по плавающей запятой .

Моя первая попытка:

var foo = new BigDecimal(myVeryLongFloatingPoint)
var bar = Math.exp(foo);
var spam = bar.divide(bar.add(new BigDecimal("1")));

привела к ошибке (где xxxxx - число с плавающей запятой):

TypeError: Object xxxxx has no method 'add'

Поэтому я попытался преобразовать bar вОбъект BigDecimal:

var foo = new BigDecimal(myVeryLongFloatingPoint)
var bar = new BigDecimal(Math.exp(foo));
var spam = bar.divide(bar.add(new BigDecimal("1")));

, что, в свою очередь, приводит к ошибке (где xxxxx - число с плавающей запятой):

BigDecimal(): Not a number: xxxxx

Куда я иду?

Является ли это разумным подходом к обработке такого рода расчетов с плавающей запятой, где требуется высокая степень точности?

Ответы [ 3 ]

2 голосов
/ 20 сентября 2011

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

  1. Вместо этого используйте 1./(1. + e^(-x)).
  2. Для больших x это приблизительно 1.-e^(-x), и чем больше x, тем лучше приближение (например, если x = 100, ваша ошибка будет в 86-й цифре).

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

2 голосов
/ 20 сентября 2011

Вы должны передать строки BigDecimal:

var bar = new BigDecimal(Math.exp(foo).toString());
1 голос
/ 20 сентября 2011

Math.exp работает только с обычными числами, а не может работать с BigDecimals.Math.exp, вероятно, преобразует foo в NaN (или что-то в этом роде), прежде чем продолжить.

Вам следует искать метод возведения в степень в вашем классе BigDecimal.Я посмотрел на источник и думаю, что есть метод BigDecimal.pow, который вы могли бы использовать вместо этого.

...