2012-02-17 32 views
13

Sẽ là một đôi bằng một số nguyên luôn luôn đúc cho số nguyên đó (giả sử là số nguyên không phải là một nguyên nhân gây tràn). Ví dụ: Math.ceil() sẽ trả về giá trị gấp đôi bằng một số nguyên. Giả sử không có tràn, nó sẽ luôn luôn đúc với cùng một số nguyên mà nó được cho là bằng?Liệu giá trị gấp đôi bằng một số nguyên luôn luôn được truyền tới số nguyên đó?

Nếu không, làm cách nào để tôi có thể làm tròn một số double thành int hoặc long?

+0

+1: câu hỏi thú vị. Tôi cho rằng câu trả lời là "có", nhưng có thể có một số trường hợp cạnh mà tôi chưa xem xét. –

Trả lời

9

Vì loại Java được cố định và Java doubles have a 52 bit mantissa, chúng có thể (dễ dàng) đại diện cho một int Java 32 bit mà không làm tròn.

+4

Phần tương ứng đại diện cho 53 -bits như bit trên được ngụ ý là 1. –

1

Tôi tin như vậy, nhưng bạn có thể kiểm tra nó tự hỏi:

public static void main(String... args) throws Exception { 
    int interactions = Integer.MAX_VALUE; 
    int i = Integer.MIN_VALUE; 
    double d = Integer.MIN_VALUE; 
    long init = System.currentTimeMillis(); 
    for (; i < interactions; i++, d++) 
     if (!(i == (int) Math.ceil(d))) 
      throw new Exception("something went wrong with i=" + i + " and d=" + d + ", Math.ceil(d)="+Math.ceil(d)); 

    System.out.println("Finished in: "+(System.currentTimeMillis() - init)+"ms"); 
} 
+0

Tôi khá chắc chắn nếu bạn làm điều đó đủ lâu lỗi làm tròn của bạn sẽ gây ra một vấn đề. (tức là 0,1 không thể được biểu diễn chính xác) –

+0

-1 bằng cách sử dụng các thử nghiệm thực nghiệm cho các lần lặp như vậy là điều xấu vì nó trong hầu hết các trường hợp sẽ đưa ra kết luận sai. –

1

Tất cả int giá trị có thể có thể được đại diện bởi một đôi mà không có lỗi. Cách đơn giản nhất để làm tròn là sử dụng Math.ceil() ví dụ:

double d = 
long l = (long) Math.ceil(d); // note: could overflow. 
+3

Tất cả các giá trị 'int' có thể, nhưng không phải tất cả các giá trị' long'. –

1

Theo kinh nghiệm, câu trả lời có vẻ là có - lưu ý rằng nó cũng hoạt động với i2 = (int) d;.

public static void main(String[] args) { 
    for (int i = Integer.MIN_VALUE + 1; i < Integer.MAX_VALUE; i++) { 
     double d = i; 
     int i2 = (int) Math.ceil(d); 
     if (i != i2) { 
      System.out.println("i=" + i + " and i2=" + i2); //Never executed 
     } 
    } 
} 
+0

Bạn cũng cần thử số âm nhưng chúng cũng hoạt động. –

+0

được sửa đổi để bắt đầu từ Integer.MIN_VALUE – assylias

+0

-1 bằng cách sử dụng các thử nghiệm theo kinh nghiệm cho các lần lặp lại như vậy là điều xấu vì hầu hết các trường hợp sẽ đưa ra kết luận sai. –

6

Có, nó sẽ chuyển đổi chính xác. Này được mô tả trong Section 5.1.3 của JLS, mà đề cập

Ngược lại, nếu các số dấu chấm động không phải là một vô cực, giá trị dấu chấm động được làm tròn đến một giá trị số nguyên V, làm tròn về phía không sử dụng IEEE 754 tròn về phía-zero chế độ ...

Kể từ double của bạn chính xác bằng với int, giá trị "tròn" chỉ là giá trị chính xác như nhau, nhưng bạn có thể đọc spec để biết chi tiết.

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