【发布时间】:2011-09-14 13:47:57
【问题描述】:
快速提问。
这总是真的吗?
int i = ...;
double d = i;
if (i == (int) d) ...
或者我需要四舍五入才能确定?
if (i == Math.round(d)) ...
【问题讨论】:
标签: java type-conversion primitive
快速提问。
这总是真的吗?
int i = ...;
double d = i;
if (i == (int) d) ...
或者我需要四舍五入才能确定?
if (i == Math.round(d)) ...
【问题讨论】:
标签: java type-conversion primitive
是的,所有可能的int 值都可以安全地往返于double。
您可以使用以下代码进行验证:
for (int i = Integer.MIN_VALUE; ; i++) {
double d = i;
if (i != (int) d) {
throw new IllegalStateException("i can't be converted to double and back: " + i);
}
if (i == Integer.MAX_VALUE) {
break;
}
}
请注意,我没有使用普通的 for 循环,因为它会跳过 Integer.MAX_VALUE 或无限循环。
请注意,int/float 或 long/double! 的情况不是相同!
【讨论】:
Integer.MAX_VALUE 的测试。
int/float 和 long/double 更多的是容量问题,而不是四舍五入,对吧?
int i = 16777217; float f = i; int d = (int)f; 现在 d 是 16777216 !
如果您的计算机速度较慢或没有时间运行循环来检查自己,Java 语言规范的相关部分在这里§ 5.1.2 Widening Conversions:
以下 19 种基本类型的特定转换称为加宽基本类型转换:
- byte 到 short、int、long、float 或 double
- 短于 int、long、float 或 double
- char 转换为 int、long、float 或 double
- int 到 long、float 或 double
- long to float or double
- 浮点数加倍
加宽基元转换不会丢失有关数值整体大小的信息。 确实,从整数类型扩大到另一种整数类型以及从 float 到 double 的转换完全不会丢失任何信息;数值被完全保留。 [...]
(以下部分 § 5.1.3 Narrowing Primitive Conversions 确保返回的方式 double -> int 也不会丢失任何信息。)
【讨论】:
int<->float,它在-2147483647 上刹车。往返后变为-2147483648
float -> int 不过是一种缩小转换,可能会丢失信息。
Joachim 解决方案的变体。
int i=Integer.MIN_VALUE;
do {
if(i != (int)(double) i) throw new AssertionError(i + " != (int)(double) "+i);
} while(i++ < Integer.MAX_VALUE);
找出导致浮点转换出错的最小值。
int i = 0;
do {
if(i != (int)(float) i) throw new AssertionError(i + " != (int)(float) "+i);
} while(i++ < Integer.MAX_VALUE);
打印
java.lang.AssertionError: 16777217 != (int)(float) 16777217
【讨论】: