java表达式中的2L vs 2

时间:2018-05-25 19:54:31

标签: java

sum=(sum+2L*(A.length-count1[i])*count1[i])%1000000007;
sum=(sum+2*(A.length-count1[i])*count1[i])%1000000007;

这两个陈述之间的区别是什么? 它与溢出有什么关系?

count1 =>整数类型数组
sum => long type。

第一个语句提交我的代码但第二个语句在某些情况下导致溢出 不会在代码中自动输入java类型2 2L如何使它与众不同。

2 个答案:

答案 0 :(得分:2)

  

代码中的java类型会不会自动生成2?

不,Java不会自动将代码2转换为long。由于运算符的优先级,Java将在添加之前执行乘法运算。这意味着2int将乘以(A.length-count1[i])intcount1[i]int,从而产生int。只有将sum long添加到long时,才会将该产品提升为2L

  

2L如何使它与众不同?

当您在代码中放置long时,这是int字面值,因此乘法会在乘法之前将其他long提升为int,从而使计算正确防止溢出。

这里要了解的基本规则是:

  • Java具有运算符优先级。在这里,对于数学,这遵循数学规则:*,/,+之前的%, - 和()s先于其他任何东西。
  • Java将通过二进制数字促销至少提升2L。如果其中一种数据类型比另一种数据类型“更高”,则在操作员计算结果之前,另一个值将提升为该类型。
  • 但Java不会根据发生的任何溢出来提升类型。您作为开发人员必须预测可能的溢出并相应地键入您的变量和值,例如在这里使用 "LOAD DATA LOCAL INFILE file INTO ..." ^^^^

答案 1 :(得分:0)

除了@rgettman已经说过,知道大多数相同优先级的表达式从左到右进行评估也很重要。

以下代码片段试图说明整个故事:

    long sum = 0;
    int largeInt = Integer.MAX_VALUE;
    long someLong = 1L; // could be 1 as well

    assertNotEquals(2L * largeInt, 2 * largeInt);

    assertNotEquals(sum + 2L * largeInt * someLong, sum + 2 * largeInt * someLong);
    assertEquals(   sum + someLong * 2L * largeInt, sum + someLong * 2 * largeInt); // same as before, just in different order

所有这些断言都会因为优先权和从左到右的评价而成功。