JavaScript长整型数据类型

65

我在JavaScript中见过一个最奇怪的东西。 服务器端(Spring):

   @RequestMapping(value = "/foo", method = RequestMethod.GET)
   @ResponseBody
   public Long foo() {
      return 793548328091516928L;
   }

我返回一个单独的长整型值并且:

$.get('/foo').done(function(data){
    console.log(data);
});

它将长整数表示为“793548328091516900”,将最后两个数字替换为0(实际上是四舍五入)。当我从任何浏览器的地址栏中进行GET请求时,数字被正确表示;因此,在我看来,这是一个js问题。

从服务器返回一个字符串而不是长整数,并使用以下方式处理:

var x = new Number(data).toFixed();

显然这是个问题。但不幸的是,我需要处理一个复杂的POJO(转换为JSON),其中一些字段(有些是嵌套的)被定义为java.lang.Long类型。如果我尝试将这个POJO强制转换为另一个没有Long类型字段的对象,就会很麻烦。

有没有更清晰的解决方法?


值得注意的是,ECMAScript规范的最新草案(https://tc39.es/ecma262/#sec-bigint-objects)现在具有BigInt类型(尽管浏览器支持不稳定)。但是,JSON尚不支持BigInt。因此,现在真正的问题在于序列化/反序列化,而不是JavaScript本身。 - Sydney
3个回答

104

在Java中,您拥有64位整数,并且这就是您正在使用的。

在JavaScript中,所有数字都是64位浮点数。这意味着您无法在JavaScript中表示所有Java longs。尾数的大小约为53位,这意味着您的数字793548328091516928无法作为JavaScript数字精确地表示。

如果您真的需要处理这些数字,则必须以另一种方式表示它们。这可以是字符串,也可以是特定表示,例如数字数组。JavaScript中提供了一些“大数字”库。


7
@px5x2没有基于"JavaScript数字"的解决方案。最好的解决方案取决于确切的需求。如果您只想显示它们,请将它们作为字符串发送。 - Denys Séguret
5
@R.Moeller 时区?您确定您评论的是正确答案吗? - Denys Séguret
2
@dystroy 你是对的,因为这个问题通常出现在长时间戳/日期上,我自己已经隐含地把它放到了问题中 :-) - R.Moeller
3
刚刚发现了这个事实...... 这简直是太疯狂了,Javascript 的设计太糟糕了。真是让人无语。 - Guillaume F.
为什么你不能将两个整数组合成一个长整型并对它们进行计算?或者使用四个字节数组? - Andrey Chaschev
显示剩余5条评论

11

可能会晚些,但肯定会帮助那些第一次遇到这种情况的人。

我也想在JavaScript中进行一些大数字的计算。有很多库可用于处理这样的数字。但它们中的大多数可能会浪费你很多时间。 在这里,https://github.com/peterolson/BigInteger.js 是一个直接、完整(适用于非Node环境和Node JS环境)且可用于所有大数字操作的工作解决方案。 或者您可以找到以下简单且有效的HTML代码片段,用于计算模数/余数:

<script src="http://peterolson.github.com/BigInteger.js/BigInteger.min.js"></script>
<script type="text/javascript">
    function modTest(){
       var rem = bigInt("1738141852226360940").mod("32").valueOf();
       console.log(rem);
       document.getElementById("remainder").innerHTML = rem;
    }
</script>

<BODY onload="modTest();">
    <p id="remainder"></p>
</BODY>

4

您可以使用long npm包。

它使您可以在JavaScript中使用64位整数。

您也可以使用BigInt JavaScript内置方法。


2
请注意,BigInt 的浏览器兼容性 - https://caniuse.com/#feat=bigint - Rahul Desai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接