將一個double等於一個整數總是強制轉換爲該整數(假設double不是導致溢出的整數)。示例:Math.ceil()將返回等於整數的double。假設沒有溢出,它是否總是會拋出與它相同的整數?將等於一個整數總是等於一個整數嗎?
如果不是,我怎樣才能將double
整理成int
或long
?
將一個double等於一個整數總是強制轉換爲該整數(假設double不是導致溢出的整數)。示例:Math.ceil()將返回等於整數的double。假設沒有溢出,它是否總是會拋出與它相同的整數?將等於一個整數總是等於一個整數嗎?
如果不是,我怎樣才能將double
整理成int
或long
?
由於Java類型是固定的,Java doubles have a 52 bit mantissa,它們可以(容易)代表一個32位的Java int的沒有四捨五入。
尾數代表53作爲最高位的比特被暗示爲1。 – 2012-02-17 10:14:27
我相信是這樣,但你可能會測試它自己:
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.1不能完全表示) – 2012-02-17 09:57:14
-1使用經驗測試來進行迭代是非常邪惡的,因爲它在大多數情況下會提供錯誤的結論。 – 2012-02-17 10:02:52
所有可能int
值可以通過雙無誤地表示。最簡單的方法是使用Math.ceil()例如
double d =
long l = (long) Math.ceil(d); // note: could overflow.
所有'int'值可以但不是全部'long'值。 – 2012-02-17 10:02:19
根據經驗,答案似乎是肯定的 - 注意它也適用於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
}
}
}
你也需要嘗試負數,但他們也工作。 – 2012-02-17 09:58:49
修改爲從Integer.MIN_VALUE – assylias 2012-02-17 10:01:42
-1開始,對這樣的迭代使用經驗測試是邪惡的,因爲它在大多數情況下會提供錯誤的結論。 – 2012-02-17 10:03:03
是的,它會完全轉換。這在JLS,其中提到
否則,如果浮點數不是無窮大的Section 5.1.3描述的, 浮點值舍入到一個整數值,V,朝着使用IEEE 零舍入754圓向零模式...
由於您double
正好等於int
的「四捨五入」值只是完全相同的值,但你可以閱讀的細節規範。
+1:有趣的問題。我會假設答案是「是」,但可能有一些我沒有考慮過的邊緣案例。 – 2012-02-17 09:50:16