2010-06-19 44 views
11

Tôi đã thực hiện một số tìm kiếm trên google, nhưng tôi dường như không thể tìm thấy những gì tôi đang tìm kiếm. Tôi đang cố gắng tìm hiểu một số thông tin chi tiết về cách làm việc số học trong Java. Ví dụ, nếu bạn thêm hai thời gian dài với nhau là điều này bằng cách sử dụng cùng một toán tử bổ sung được sử dụng khi thêm hai int với nhau? Ngoài ra, những gì đang xảy ra dưới mui xe khi bạn kết hợp chờ đợi và ints trong các biểu thức số học như thế này:Java số học int so với dài

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

result = a + b; 

Nếu bất cứ ai có thể làm sáng tỏ về vấn đề này hoặc post link dẫn tới bài viết có liên quan đó sẽ là tuyệt vời. Cảm ơn!

EDIT: Cảm ơn bạn đã trả lời cho đến thời điểm này. Ngoài ra, nó có an toàn để thực hiện số học với các nguyên thủy khác nhau miễn là bạn đang gán vào một biến của kiểu nguyên thủy rộng nhất trong biểu thức của bạn?

+2

Đây không phải là diễn đàn, nó không thực sự minh bạch đối với những người đã trả lời câu hỏi của bạn rằng bạn đã theo dõi. Đối với chỉnh sửa của bạn mặc dù: Java sẽ không cho phép bạn gán kết quả của một hoạt động cho một biến nếu biến không phải là kiểu nguyên thủy "rộng" đủ để giữ nó.Nói cách khác, bạn không thể gán kết quả của "0L + 1" cho một int mà không cần phải đặc biệt đúc vào một int. –

+0

Ah ok, điều đó có ý nghĩa. Cảm ơn đã theo lên. – BordrGuy108

+0

Không hoàn toàn an toàn vì nhiều thao tác có thể dẫn đến tràn hoặc tràn. thử Long.MAX_VALUE + 1 Tuy nhiên, nó sẽ luôn biên dịch nếu bạn gán cho loại rộng nhất. –

Trả lời

15

khi pha trộn các loại int được tự động mở rộng thành một khoảng thời gian dài và sau đó hai lần được thêm vào để tạo kết quả. Các java language spec có các ví dụ tốt cho các hoạt động có chứa các loại nguyên thủy khác nhau.

Cụ thể, đây là những loại mỗi ý primative mở rộng để mà không đòi hỏi một dàn diễn viên:

  • byte để short, int, long, float, hoặc đôi
  • ngắn để int, long, float, hoặc đôi
  • char sang int, long, float, hoặc đôi
  • int dài, float, hoặc đôi
  • dài nổi hoặc đôi
  • phao để đôi
+0

Tôi cho rằng điều này sẽ sửa liên kết bị hỏng: http://docs.oracle.com/javase/specs/jls/se5.0/html/conversions.html#5.6 – Chris

7

Xem: Conversions and promotions

Theo đó, int của bạn được thăng long và sau đó được đánh giá.

Tương tự như vậy, ví dụ: int + double và phần còn lại của số nguyên thủy. I E.

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

Đối với nhà điều hành bổ sung Tôi cũng giống như vậy, nhưng tôi không có bất kỳ tham chiếu nào về nó.

Chế độ xem nhanh nguồn của trình biên dịch cho thấy chúng khác nhau.

Cụ thể iadd cho int cộng và ladd bổ sung dài:

Xem mẫu này mã:

$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 
$ 

Khi biên soạn mã byte được tạo ra là thế này:

$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 

} 

Nhìn vào dòng 16 nó nói: iadd (để thêm vào) trong khi dòng 22 nói ladd (ví Ngoài dài)

Ngoài ra, nó là an toàn để thực hiện số học với nguyên thủy khác nhau, miễn là bạn đang gán vào một biến kiểu nguyên thủy rộng nhất trong biểu hiện của bạn?

Vâng, và nó cũng "an toàn" để thực hiện số học với kích thước nhỏ hơn, theo nghĩa, họ không phá vỡ các chương trình, bạn chỉ mất thông tin.

Ví dụ, hãy thử thêm Integer.MAX_VALUE để Integer.MAX_VALUE để xem những gì sẽ xảy ra, hoặc int x = (int) (Long.MAX_VALUE - 1);

3

Ngoài ra, nó là an toàn để thực hiện số học với nguyên thủy khác nhau, miễn là bạn đang gán vào một biến kiểu nguyên thủy rộng nhất trong biểu hiện của bạn?

Điều đó phụ thuộc vào ý bạn là an toàn. Nó chắc chắn sẽ không tránh bạn cần phải xem xét khả năng tràn.

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

Sự khác biệt chính là với a = a + b, không có typecasting xảy ra, và do đó trình biên dịch nổi giận với bạn vì không typecasting. Nhưng với a += b, những gì nó thực sự làm là typecasting b đến a loại tương thích với a.

+0

Vì vậy, nó sẽ tạo ra một downcast ẩn từ 'long' thành' int', có khả năng ném đi thông tin? Chỉ cần đi qua điều này trong 'java.io.ByteArrayInputStream # bỏ qua (dài)' và đã làm một đôi-mất. Chưa bao giờ thấy điều đó trước đây. – nilskp

1

Ví dụ đơn giản này có thể xóa các nghi ngờ về chuyển đổi loại dữ liệu trong trường hợp hoạt động số học trong 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 

Sau đây là thứ tự của các kiểu dữ liệu theo phạm vi trong java:

byte<short<int<long<float<double 

Đây là thứ tự trong đó mở rộng sẽ xảy ra.

Lưu ý: phao có nhiều dải dài hơn nhưng có kích thước nhỏ hơn.

Các vấn đề liên quan