将一个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