在 Javascript 中使用 Math.exp() 和 BigDecimal 来处理大浮点数
我正在尝试在 Javascript 中执行以下计算:
e^x / (1 + e^x)
其中 x 是一个长浮点数。
在本例中,我要求精度至少到小数点后第十位。
我一直在使用 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
我哪里出错了?
这是处理这种需要高精度的浮点计算的明智方法吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您应该将字符串传递给 BigDecimal:
You should pass strings to
BigDecimal
:有一些可能有用的数学方法。如果 x 为正且相当大,那么您将采用两个大数的比率,这将降低您的最终精度。相反,您可以:
1./(1. + e^(-x))
代替。1.-e^(-x)
,x 越大,近似效果越好(例如,如果 x=100,则你的错误将在第 86 位)。(老实说,在使用它之前应该验证一下,我只是在这里失去记忆,没有写下任何东西,但如果这看起来有用,我可以拿一支铅笔......)
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./(1. + e^(-x))
instead.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 仅适用于普通数字,无法对 BigDecimal 进行操作。 Math.exp 可能在继续之前将 foo 转换为 NaN (或类似的东西)。
您应该在 BigDecimal 类中寻找求幂方法。我查看了源代码,我认为您可以使用 BigDecimal.pow 方法来代替。
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.