gpt4 book ai didi

javascript - 如何在 jjs/Nashorn 中使用 java.math.BigInteger?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:07:20 25 4
gpt4 key购买 nike

我想在 nashorn/jss JavaScript 中使用 java.math.BigInteger。

举例来说,假设我想计算斐波那契数列。数字需要保持精确,即使它们变得非常大。

工作的 Java 代码如下所示:

public static BigInteger fibonacci(int n) {
BigInteger prev = new BigInteger("0");
if (n == 0) return prev;

BigInteger next = new BigInteger("1");
if (n == 1) return next;

BigInteger fib = null;
int i;
for (i = 1; i < n; i++) {
fib = prev.add(next);
prev = next;
next = fib;
}
return fib;
}

我们可以测试:

  • n=77: 5527939700884757
  • n=78: 8944394323791464
  • n=79: 14472334024676221

到目前为止一切顺利。

下面等效的 JavaScript 代码:

function fibonacci(n) {
var BigInteger = Java.type("java.math.BigInteger");
prev = new BigInteger("0");
if (n == 0) return prev;

next = new BigInteger("1");
if (n == 1) return next;

var i, fib = null;
for (i = 1; i < n; i++) {
fib = prev.add(next);
prev = next;
next = fib;
}
return fib;
}

现在我们得到:

  • n=77: 5527939700884757
  • n=78: 8944394323791464
  • n=79: 14472334024676220

请注意,79 的值是一个错误 - 这是错误的。

我怀疑问题出在某个地方,BigNumber 值被重新解释为纯 JavaScript 数字。 (通过“某处”,我怀疑这已经发生了,因为假定的 BigInteger 被传递给了 .add 方法)

例如,如果我这样做:

var BigInteger = Java.type("java.math.BigInteger");
print(new BigInteger("14472334024676221"));

输出是 14472334024676220,而不是 14472334024676221。即使我在 BigInteger 对象上显式调用 .toString() 也会发生这种情况。

我如何克服这个问题?

更新:@Dici 问我是否寻找阈值。我做了 - 我发现:

var str, BigInteger = Java.type("java.math.BigInteger");
str = "9999999999999998";
print(str + ": " + new BigInteger(str));
str = "9999999999999999";
print(str + ": " + new BigInteger(str));

将输出:

  • 9999999999999998: 9999999999999998
  • 9999999999999999: 10000000000000000

我不确定这是“阈值”问题,还是某些特定数字不准确。

更新 2:

这现在被报告为错误:https://bugs.openjdk.java.net/browse/JDK-8146264错误报告是由 Oracle JDK/Nashorn 开发人员完成的,所以我想这是真的。祈祷吧。

最佳答案

是的,这是一个问题。已提交错误 -> https://bugs.openjdk.java.net/browse/JDK-8146264

JSType 和其他一些地方有“instanceof Number”检查——不确定单独修复 JSType.toStringImpl 是否可行。无论如何,我有一个解决方法 - 不是很漂亮 - 但仍然是一个解决方法。您可以在这些对象上调用 java.lang.Object.toString 方法,从而避免 Nashorn 的 JSType 字符串转换代码。

function fibonacci(n) {
var BigInteger = Java.type("java.math.BigInteger");
prev = new BigInteger("0");
if (n == 0) return prev;

next = new BigInteger("1");
if (n == 1) return next;

var i, fib = null;
for (i = 1; i < n; i++) {
fib = prev.add(next);
prev = next;
next = fib;
}
return fib;
}

function javaToString(obj) {
var javaToStringMethod = (new java.lang.Object()).toString;
var call = Function.prototype.call;
return call.call(javaToStringMethod, obj);
}

print(javaToString(fibonacci(77)))
print(javaToString(fibonacci(78)))
print(javaToString(fibonacci(79)))

var str, BigInteger = Java.type("java.math.BigInteger");
str = "9999999999999998";
print(str + ": " + javaToString(new BigInteger(str)));
str = "9999999999999999";
print(str + ": " + javaToString(new BigInteger(str)));

关于javascript - 如何在 jjs/Nashorn 中使用 java.math.BigInteger?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34502968/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com