Java算术int与long

时间:2010-06-19 00:38:43

标签: java math

我在google上做了一些搜索,但我似乎无法找到我正在寻找的东西。我试图找出有关算术在Java中运行方式的一些详细信息。例如,如果将两个长片一起添加,则使用在将两个整数添加到一起时使用的相同加法运算符?另外,当你在这样的算术表达式中混合long和int时,会发生什么:

long result;
long operand a = 1;
int operand b = 999999999;

result = a + b;

如果有人能够对此有所了解或发布相关文章的链接,那将是非常棒的。谢谢!

编辑:感谢您的回复。另外,只要在表达式中分配最宽基元类型的变量,用不同的基元执行算术是否安全?

7 个答案:

答案 0 :(得分:15)

当混合类型时,int会自动加宽为long,然后添加两个long以生成结果。 Java Language Specification解释了包含不同主要类型的操作过程。

具体来说,这些类型是每个主要的扩展到不需要演员的类型:

  • byte to short,int,long,float或double
  • 简称为int,long,float或double
  • char to int,long,float或double
  • int to long,float或double
  • 长期漂浮或加倍
  • 浮动加倍

答案 1 :(得分:7)

请参阅:Conversions and promotions

根据这一点,您的int会提升为long,然后进行评估。

例如,int + double和其他原语也是如此。即

System.out( 1 + 2.0 );// prints 3.0 a double

至于加法运算符我几乎是相同的,但我没有任何参考。

编译器源代码的快速浏览显示它们不同。

即添加int iadd和长添加ladd

请参阅此示例代码:

$cat Addition.java 
public class Addition {
    public static void main( String [] args ) {
        int  a  = Integer.parseInt(args[0]);
        long b = Long.parseLong(args[0]);
        // int addition 
        int  c  = a + a;
        // long addition 
        long d = a + b;
    }
}
$javac Addition.java 
$

编译时生成的字节码是:

$javap -c Addition 
Compiled from "Addition.java"
public class Addition extends java.lang.Object{
public Addition();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   aload_0
   1:   iconst_0
   2:   aaload
   3:   invokestatic    #2; //Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
   6:   istore_1
   7:   aload_0
   8:   iconst_0
   9:   aaload
   10:  invokestatic    #3; //Method java/lang/Long.parseLong:(Ljava/lang/String;)J
   13:  lstore_2
   14:  iload_1
   15:  iload_1
   16:  iadd
   17:  istore  4
   19:  iload_1
   20:  i2l
   21:  lload_2
   22:  ladd
   23:  lstore  5
   25:  return

}

查看第16行:iadd(对于int添加),而行22表示ladd(长期添加)

  

此外,只要您在表达式中指定最宽基元类型的变量,用不同的基元执行算术是否安全?

是的,并且“安全”以较小的尺寸执行算术,从某种意义上说,它们不会破坏程序,只会丢失信息。

例如,尝试将Integer.MAX_VALUE添加到Integer.MAX_VALUE以查看会发生什么,或int x = ( int ) ( Long.MAX_VALUE - 1 );

答案 2 :(得分:3)

  

此外,只要您在表达式中指定最宽基元类型的变量,用不同的基元执行算术是否安全?

这取决于你的安全意味着什么。它当然不会避免你需要考虑溢出的可能性。

答案 3 :(得分:3)

这称为算术推广。有关详细信息,请查看http://www.cafeaulait.org/course/week2/22.html

答案 4 :(得分:2)

int a=5;  
long b=10;  
a+=b;  
System.out.println(a);

主要区别在于a = a + b,没有进行类型转换,因此编译器因为没有进行类型转换而对你生气。         但是对于a += b,它真正做的是将b类型转换为与a兼容的a类型。

答案 5 :(得分:1)

这个简单的例子可以清除对java中算术运算情况下数据类型转换的疑虑。

    byte a = 1;
    short b = 1;
    System.out.println(a+b);                     //Output = 2
    Object o = a+b;                              //Object becomes int
    System.out.println(o.getClass().getName());  //Output = java.lang.Integer

    int c = 1;
    System.out.println(a+b+c);                   //Output = 3
    o = a+b+c;                                   //Object becomes int
    System.out.println(o.getClass().getName());  //Output = java.lang.Integer

    long d = 1l;
    System.out.println(a+b+c+d);                 //Output = 4
    o = a+b+c+d;                                 //Object becomes long
    System.out.println(o.getClass().getName());  //Output = java.lang.Long

    float e = 1.0f;
    System.out.println(a+b+c+d+e);               //Output = 5.0
    o = a+b+c+d+e;                               //Object becomes float
    System.out.println(o.getClass().getName());  //Output = java.lang.Float

    double f = 1.0;
    System.out.println(a+b+c+d+e+f);             //Output = 6.0
    o = a+b+c+d+e+f;                             //Object becomes double
    System.out.println(o.getClass().getName());  //Output = java.lang.Double

以下是根据java中的范围的数据类型的顺序:

    byte<short<int<long<float<double

这是扩大的顺序。

注意:float的范围比long长,但是尺寸更小。

答案 6 :(得分:0)

答案指出了算术提升。但是考虑到这一点,我陷入了以下陷阱(我感到羞耻),在这里我要指出: 如果对我来说有两个以上的操作数,则似乎计算是从左到右执行的,并且如果焦点上的实际两个操作数具有不同的类型,则会进行算术提升。 因此,以下代码对于s1和s2产生不同的结果。我对此的解释是: 在计算s1时,首先将a和b作为两个整数相加(并且发生溢出),然后向c的结果(一个long)中相加。 在计算s2时,首先将c和b相加(只要很长),然后再相加a(提升很长时间),这样就不会发生溢出。

final int a = Integer.MAX_VALUE;
final int b = 1;
final long c = 1L;
final long s1 = a + b + c;
final long s2 = c + b + a;
System.out.println("s1=" + s1 + ", s2=" + s2);

输出将是: s1=-2147483647, s2=2147483649