JavaScript 中的计算结果与 Java 中的计算结果不同
Different calculation outcome in JavaScript than in Java
大数字的问题。
Java中的计算:
int n = 4451 + 554 * 57;
n = n << 13 ^ n;
System.out.println(n * (n * n * 15731 + 789221) + 1376312589);
=> 587046333
在 JavaScript 中:
var n = 4451 + 554 * 57;
n = n << 13 ^ n;
console.log(n * (n * n * 15731 + 789221) + 1376312589);
=> 4.043454188561781e+29
JavaScript版本有什么问题,我该如何解决它,以便JavaScript的结果与Java的结果相同?
编辑:尝试使用:https://github.com/jtobey/javascript-bignum,但结果为0
var test = new BigInteger(295120061).multiply( new BigInteger(295120061)
.multiply(new BigInteger(295120061))
.multiply(new BigInteger(15731))
.add(new BigInteger(789221)))
.add(new BigInteger(1376312589));
=>测试 = 0
JavaScript 没有整数算术,所有数字都存储为 64 位浮点数(在 Java 中double
)。 当 JavaScript 看到像 <<
或 ^
这样的位处理运算符时,它会暂时将操作数转换为 32 位整数以执行算术运算,但随后将它们转换回 64 位浮点数。 因此,最后一个乘法在 JavaScript 中作为浮点运算执行。 在 Java 中,它仍然是一个整数操作。 这段代码在 Java 中执行相同的操作(我现在已经测试过了,结果是一样的):
int n = 4451 + 554 * 57;
n = n << 13 ^ n;
double x = n;
System.out.println(x * (x * x * 15731 + 789221) + 1376312589);
如果你想要与Java相同的JavaScript代码,你将需要一种方法来执行乘法和加法,其工作方式与Java在溢出时的工作方式相同。 也就是说,它必须将所有操作的结果视为在 -2 31 和 231-1 范围内。 在 JavaScript 中使用其原生算术确实没有可靠的方法来做到这一点;即使你给它两个只有 31 个有效位的值,当你将它们相乘时,你会得到 62 个有效位,而 JavaScript 的"数字"类型只有 52 位,这意味着一些位会丢失。 可能有一个JavaScript库可以让你做这种精确的整数算术,但我不是JavaScript框架的专家,所以我不知道那会是什么。 也许其他人会插话。
正如@ajb所说,问题在于 JavaScript 是松散类型的,并且执行双精度浮点运算,而我们需要严格的 32 位整数算术。
对于乘法,函数Math.imul
为此目的而存在。Internet Explorer 尚不支持它,但链接页面包含一个替换函数,该函数模拟旧版浏览器的imul
,该功能的工作原理是分别将数字的上半部分和下半部分相乘。
对于加法,我们可以用 0 或数字。这是有效的,因为任何按位操作都会强制 JavaScript 数字变成 32 位整数,而 0 的 ORing 实际上不会更改超出此值的值:
Math.iadd = function(a, b) { return ((a|0) + (b|0))|0; }
现在使用它:
var n = Math.iadd(4451, Math.imul(554, 57));
n = n << 13 ^ n;
console.log(Math.iadd(Math.imul(n, Math.iadd(Math.imul(Math.imul(n, n), 15731), 789221)), 1376312589));
有点长和凌乱,但它有效。输出是587046333的,与Java相同。
使用: https://github.com/iriscouch/bigdecimal.js
var n = 4451 + 554 * 57;
n=n << 13 ^ n;
var test = new BigDecimal(n).multiply( new BigDecimal(n)
.multiply(new BigDecimal(n))
.multiply(new BigDecimal(15731))
.add(new BigDecimal(789221)))
.add(new BigDecimal(1376312589));
test.intValue()
打印正确的结果
- if(foo!==null)的计算结果为true,即使foo为null
- ngIf的计算结果始终为true
- 设置为负数的变量计算结果为true
- 如何在模态助推器中显示计算结果(JS)
- 将javascript计算结果自动放入HTML表单中
- JavaScript/jQuery:格式化日期计算结果的最佳方式
- 使用AngularJS从服务器获取计算结果
- 如果ng-if的计算结果为false,AngularJS会使我的模型数据无效
- 计算结果Javascript中不同数字的数量
- javascript/html获胜't显示计算结果
- 使正数的计算结果为真,使负数计算为假
- Javascript 无法计算结果
- 为什么 {} == false 的计算结果为 false,而 [] == false 的计算结果为 true
- 以 HTML 格式显示计算结果 (javascript)
- 如果 x = 3 且 z 未分配,为什么 z = x-- - --x 的计算结果为 2
- 为什么 _=$=+[],++_+''+$ 的计算结果为 10
- 如何使用 ng-class 在值计算结果为零时删除类
- 为什么Number.MIN_VALUE < -1219312(或任何小值)的计算结果为 false
- 为什么空的 JavaScript 数组在条件结构中的计算结果为 true
- JavaScript 中的计算结果与 Java 中的计算结果不同