乘法时发生溢出

2022-09-02 23:00:21
long m = 24 * 60 * 60 * 1000 * 1000;

上面的代码会创建溢出,并且不会打印正确的结果。

long m2 = 24L * 60 * 60 * 1000 * 1000;
long m3 = 24 * 60 * 60 * 1000 * 1000L;

上面的 2 行打印正确的结果。

我的问题是-

  1. 这对我使用的编译器重要吗?或者?m2m3
  2. Java是如何开始乘法的?从左到右还是从右到左?24*60 是先计算还是 1000*1000?

答案 1

在这种情况下 -

long m = 24 * 60 * 60 * 1000 * 1000;  

首先评估分配的权利。右侧没有类型数据。都是.因此,尝试将结果拟合到然后发生溢出。longintJVMint

在第二种情况下 -

long m2 = 24L * 60 * 60 * 1000 * 1000;
long m3 = 24 * 60 * 60 * 1000 * 1000L;

这里乘法的一个操作数是 。因此,其他系统会自动提示。结果是尝试适合 .最后,使用 和 完成分配。longlonglongm2m3

是的,从左到右乘法的结合性 - 意味着首先取左操作数。基于这一事实,我认为在这种情况下我们应该使用 -

long m2 = 24L * 60 * 60 * 1000 * 1000;  

这个声明,因为在声明中,提升到更早的地方,从而降低了溢出的风险。long


答案 2

我会使用线条而不是线条。m2m3

Java 从左到右计算乘法运算符,因此首先进行计算。*24 * 60

碰巧的是(一)不会溢出,因此当你乘以(第二个)时,产品在乘法之前被提升到,这样就不会发生溢出。24 * 60 * 60 * 100010001000L1000long

但是,正如您在评论中提到的,在乘以最后一个数字之前,更多的因素可能会导致数据类型溢出,从而产生不正确的答案。最好对第一个(最左边的)数字使用文字,以避免从一开始就溢出。或者,您可以将第一个文字转换为 ,例如 。intlonglongm2long(long) 24 * 60 * ...


推荐