【问题标题】:Using Math.exp() in Javascript with BigDecimal for large floating point numbers在带有 BigDecimal 的 Javascript 中使用 Math.exp() 处理大浮点数
【发布时间】:2011-11-21 05:13:32
【问题描述】:

我正在尝试在 Javascript 中执行以下计算:

e^x / (1 + e^x)

其中x 是一个长浮点数。

在这种情况下,我要求至少精确到小数点后 10 位。

我一直在使用BigDecimal 来准确处理浮点数,正如The Floating Point Guide 所建议的那样。

我的第一次尝试:

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

我哪里错了?

这是处理这种需要高精度的浮点计算的明智方法吗?

【问题讨论】:

  • 使用常规(二进制)浮点数有什么问题?如果是你正在溢出,为什么不以等效形式1 / (1 + e^-x) 重写表达式并将其用于正值x
  • 谢谢,我会玩这个的。

标签: javascript math bigdecimal


【解决方案1】:

您应该将字符串传递给BigDecimal

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

【讨论】:

  • 谢谢 - 这为我修好了。
【解决方案2】:

有一些数学方法可能有用。如果x 是正数且相当大,那么您将采用两个大数的比率,这将降低您的最终精度。相反,您可以:

  1. 请改用1./(1. + e^(-x))
  2. 对于较大的 x,这大约是 1.-e^(-x),x 越大,近似值越好(例如,如果 x=100,那么您的错误将在第 86 位)。

(老实说,在使用它之前应该先验证一下,我只是在这里失忆了,没有写下任何东西,但如果这看起来有用,我可以拿支铅笔......)

【讨论】:

    【解决方案3】:

    Math.exp 仅适用于普通数字,不能 对 BigDecimal 进行操作。 Math.exp 可能在继续之前将 foo 转换为 NaN(或类似的东西)。

    您应该在 BigDecimal 类中寻找求幂方法。我查看了源代码,我认为您可以使用 BigDecimal.pow 方法。

    【讨论】:

      猜你喜欢
      • 2014-04-10
      • 2022-01-20
      相关资源
      最近更新 更多