admin管理员组

文章数量:1415137

I'm attempting to perform the following calculation in Javascript:

e^x / (1 + e^x)

where x is a long floating point number.

In this instance, I require accuracy to at least the 10th decimal place.

I've been using BigDecimal to accurately handle the floating point numbers, as suggested at The Floating Point Guide.

My first attempt of:

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

led to the error (where xxxxx is the floating point number):

TypeError: Object xxxxx has no method 'add'

So I attempted to tried convert bar into a BigDecimal object:

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

which in turn leads to the error (where xxxxx is the floating point number):

BigDecimal(): Not a number: xxxxx

Where am I going wrong?

Is this a sensible approach to handling this kind of calculation with floating points where a high degree of precision is required?

I'm attempting to perform the following calculation in Javascript:

e^x / (1 + e^x)

where x is a long floating point number.

In this instance, I require accuracy to at least the 10th decimal place.

I've been using BigDecimal to accurately handle the floating point numbers, as suggested at The Floating Point Guide.

My first attempt of:

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

led to the error (where xxxxx is the floating point number):

TypeError: Object xxxxx has no method 'add'

So I attempted to tried convert bar into a BigDecimal object:

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

which in turn leads to the error (where xxxxx is the floating point number):

BigDecimal(): Not a number: xxxxx

Where am I going wrong?

Is this a sensible approach to handling this kind of calculation with floating points where a high degree of precision is required?

Share Improve this question asked Sep 20, 2011 at 15:38 KennersKenners 531 silver badge4 bronze badges 2
  • 1 What goes wrong with using regular (binary) floats? If it's that you're getting overflow, why not rewrite the expression in the equivalent form 1 / (1 + e^-x) and use that for positive x? – Mark Dickinson Commented Sep 20, 2011 at 18:04
  • Thanks, I'll have a play with this. – Kenners Commented Sep 29, 2011 at 22:19
Add a ment  | 

3 Answers 3

Reset to default 2

You should pass strings to BigDecimal:

var bar = new BigDecimal(Math.exp(foo).toString());

There are a few mathematical approaches that might be useful. If x is positive and reasonably large, then you're taking the ratio of two large number and this will reduce your final precision. Instead, you might:

  1. Use 1./(1. + e^(-x)) instead.
  2. For large x, this is approximately 1.-e^(-x), and the bigger x is, the better the approximation (e.g., if x=100, then your error would be in the 86th digit).

(Honestly, one should verify this before using it, I'm just going of off memory here an not writing anything down, but if this looks useful, I could grab a pencil...)

Math.exp only works on normal Numbers and cannot operate on BigDecimals. Math.exp is probably converting foo to NaN (or something like that) before continuing.

You should look for an exponentiation method inside your BigDecimal class. I looked at the source and I think there is a BigDecimal.pow method you could use instead.

本文标签: Using Mathexp() in Javascript with BigDecimal for large floating point numbersStack Overflow