为什么Java隐式(不带强制转换)将“long”转换为“float”?

为什么Java隐式(不带强制转换)将“long”转换为“float”?,java,casting,Java,Casting,每次我认为我了解铸造和转换,我发现另一个奇怪的行为 long l = 123456789L; float f = l; System.out.println(f); // outputs 1.23456792E8 考虑到long比float具有更大的位深度,我认为编译该函数需要显式强制转换。毫不奇怪,我们发现结果已经失去了精确性 为什么这里不需要强制转换?解决了这个问题: 5.1.2扩大原语转换 以下19个具体转换 在基本类型上称为 扩大原语转换: 字节到短、int、long、float或

每次我认为我了解铸造和转换,我发现另一个奇怪的行为

long l = 123456789L;
float f = l;
System.out.println(f);  // outputs 1.23456792E8
考虑到
long
float
具有更大的位深度,我认为编译该函数需要显式强制转换。毫不奇怪,我们发现结果已经失去了精确性

为什么这里不需要强制转换?

解决了这个问题:

5.1.2扩大原语转换 以下19个具体转换 在基本类型上称为 扩大原语转换:

  • 字节到短、int、long、float或double
  • 短到整数、长到浮点或双精度
  • 字符到int、long、float或double
  • int到long、float或double
  • 长到漂浮或翻倍
  • 浮动至双倍
加宽基元转换不会丢失有关数值总体大小的信息

将int或long值转换为float,或将long值转换为double,可能会导致精度损失,也就是说,结果可能会丢失一些值的最低有效位。在这种情况下,生成的浮点值将是整数值的正确四舍五入版本

换句话说,JLS区分了量级损失和精度损失

例如,
int
byte
是一种(潜在的)幅度损失,因为不能在
字节中存储500

long
float
是一种潜在的精度损失,但不是幅度损失,因为float的值范围大于long的值范围

因此,规则是:

  • 震级损失:需要显式铸造
  • 精度损失:无需铸造

微妙的?当然但我希望这能澄清这一点。

同样的问题也可以被问到
long
double
——两种转换都可能会丢失信息

说:

加宽基元转换不需要 丢失有关整个系统的信息 数值的大小。的确 积分的转换 不允许将类型转换为另一个整数类型 丢失任何信息;这个 数值被精确地保留。 从浮动到浮动的转换 strictfp表达式中的double 精确保存数值; 但是,这种转换不是 strictfp可能会丢失有关的信息 转换后的地震的总体震级 价值观

整型或长型值的转换 浮动,或长值浮动 加倍,可能导致损失 精确性也就是说,结果可能会丢失 数据的一些最低有效位 价值。在这种情况下,结果是 浮点值将是一个 正确四舍五入版本的 整数值,使用IEEE 754 四舍五入至最近模式(§4.2.4)

换句话说,即使您可能会丢失信息,您也知道该值仍将在目标类型的总体范围内

当然可以选择要求所有隐式转换完全不丢失任何信息-因此
int
long
float
将是显式的,
long
double
将是显式的。(
int
double
是可以的;
double
有足够的精度来准确表示所有
int
值。)


在某些情况下,这将是有用的——在某些情况下不是。语言设计是关于妥协的;你不可能全部赢。我不确定我会做出什么样的决定……

尽管您认为long在内部使用的比特数比float多是正确的,但java语言的工作路径正在拓宽:

字节->短->整数->长->浮点->双精度


要从左向右转换(加宽转换),不需要强制转换(这就是为什么允许长到浮动)。要从右向左转换(缩小转换),必须进行显式转换。

我在什么地方听到过这个。浮点数可以像我们写的那样以指数形式存储23500000000'存储为“2.35e10”。因此,float有空间占用long的值范围。以指数形式存储也是精度损失的原因。

我认为有理由认为,可能丢失信息的转换需要特定的转换。这些是有损转换,这可能会让开发人员大吃一惊。我可以看出,它在某些情况下是方便的,但在其他情况下是不方便的。不过,我认为询问这个可能令人困惑的选择一点也不不不合理。double或float与任何整数类型(to或from)之间的任何转换都可能导致精度损失。这在任何情况下都需要显式强制转换。依那个逻辑,为什么需要强制转换呢?int加倍可能会丢失信息吗?我以为每个整数都可以用双精度来表示。显然,走另一条路总会有潜在的损失。根据您的推理,为什么要像现在这样明确地说明
double
long
?直觉(IMO)推理是“如果你可能会丢失信息,请明确”——但这在这里并不成立。我支持jalf,似乎你完全反对强制转换。是的,double有52位尾数,这足以精确表示32位整数。再加上这个,float的最大值约为3E38,而相同位数的int为2147483647。如果将此最大值传递给int,则打印它,然后将其传递给float并再次打印;这两个值可能不同,即“您可能会丢失信息”。long大约是9E18鉴于这个问题已经有五年多的历史了,并且有多个带有投票权的答案,除了实质性的讨论之外,似乎您