为什么在 Java 中将 long 转换为 double?
Why is long casted to double in Java?
SSCCE:
public class Test {
public static void main(String[] args) {
Long a = new Long(1L);
new A(a);
}
static class A {
A(int i) {
System.out.println("int");
}
A(double d) {
System.out.println("double");
}
}
}
输出:
double
不会打印任何编译错误,它工作正常并调用 double
参数构造函数。但是为什么?
这取决于类型提升的规则:long
优先转换为 double
,而不是 int
。
A long
总是可以放入 double
, 虽然 精度 可能会 如果 long
大于 2 的 53 次方。因此您的编译器选择 double
构造函数比 int
构造函数更合适。
(编译器不会进行 dynamic 检查,因为 1L
does 适合 int
).
因为 long 不 "fit" 在 int 中。
勾选https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html
int
是 4 个字节,而 long
和 double
是 8 个字节
因此,很明显,如果将数据转换为 int,则有可能丢失 4 个字节的数据。数据类型总是向上转换。正如@Bathsheba 的评论提到的,即使使用double 也有可能丢失数据,但与int 相比丢失要小得多。
如您所见,double 使用 52 位存储有效数字。如果它选择 int,变量将有 32 位可用。因此 jvm 选择 double 而不是 int。
来源:Wikipedia
将 long
转换为 int
是 narrowing primitive conversion because it can lose the overall magnitude of the value. Converting long
to double
is a widening primitive conversion。
编译器将自动为参数生成 assignment context 转换。这包括扩大原始转换,但不包括缩小原始转换。因为带有 int
参数的方法需要缩小转换,所以它不适用于调用。
SSCCE:
public class Test {
public static void main(String[] args) {
Long a = new Long(1L);
new A(a);
}
static class A {
A(int i) {
System.out.println("int");
}
A(double d) {
System.out.println("double");
}
}
}
输出:
double
不会打印任何编译错误,它工作正常并调用 double
参数构造函数。但是为什么?
这取决于类型提升的规则:long
优先转换为 double
,而不是 int
。
A long
总是可以放入 double
, 虽然 精度 可能会 如果 long
大于 2 的 53 次方。因此您的编译器选择 double
构造函数比 int
构造函数更合适。
(编译器不会进行 dynamic 检查,因为 1L
does 适合 int
).
因为 long 不 "fit" 在 int 中。
勾选https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html
int
是 4 个字节,而 long
和 double
是 8 个字节
因此,很明显,如果将数据转换为 int,则有可能丢失 4 个字节的数据。数据类型总是向上转换。正如@Bathsheba 的评论提到的,即使使用double 也有可能丢失数据,但与int 相比丢失要小得多。
如您所见,double 使用 52 位存储有效数字。如果它选择 int,变量将有 32 位可用。因此 jvm 选择 double 而不是 int。
来源:Wikipedia
将 long
转换为 int
是 narrowing primitive conversion because it can lose the overall magnitude of the value. Converting long
to double
is a widening primitive conversion。
编译器将自动为参数生成 assignment context 转换。这包括扩大原始转换,但不包括缩小原始转换。因为带有 int
参数的方法需要缩小转换,所以它不适用于调用。