声明 long 或 float 时为什么需要“F”和“L”后缀?根据documentation :
An integer literal is of type
long
if it ends with the letterL
orl
; otherwise it is of typeint
.
A floating-point literal is of typefloat
if it ends with the letterF
orf
; otherwise its type isdouble
.
因此,显然编译器默认将这些值视为 int 数据类型或 double 数据类型。这对我来说并不能完全解释事情。
我挖得更深一点,发现了 discussion其中用户描述从 64 位 double 型转换为 32 位浮点型会导致数据丢失,设计者不想做出假设。
我还有疑问:
为什么编译器允许写入
byte myByte = 100;
,并且编译器会自动将 100(如上所述的 int)转换为字节,但编译器不会允许long myLong = 3_000_000_000;
?为什么它不会自动将 3_000_000_000 转换为 long,尽管它完全在 long 的范围内?如上所述,在设计 Java 时,设计者不会允许将 double 分配给 float,因为这样会造成数据丢失。虽然这对于超出 float 范围的值可能是正确的,但显然像 3.14 这样的值对于 float 来说已经足够小了。那么,为什么编译器会在赋值
float myFloat = 3.14;
时抛出错误?
最终,我无法完全理解为什么需要后缀,以及围绕自动转换的规则(如果这就是幕后发生的事情)等。
我知道这个话题之前已经讨论过,但给出的答案只会引发更多问题,所以我决定创建一个新帖子。
最佳答案
回答您的具体问题:
long myLong = 3_000_000_000;
的问题是3_000_000_000
不是合法的int
文字,因为 3,000,000,000 不适合 4 个字节。事实上,您想要将其提升为long
以初始化myLong
是无关紧要的。 (是的,语言设计者可以设计语言,以便在这种情况下3_000_000_000
可以被解析为long
,但他们没有这样做,可能是为了使语言更简单并避免在其他情况下出现歧义。)3.14
的问题不是范围问题,而是精度损失问题。特别是,虽然 3.14 以 10 为基数表示形式终止,但它没有二进制浮点的有限表示形式。因此,从double
转换为float
(为了初始化myFloat
)将涉及截断表示的重要非零位。 (但需要明确的是:Java 认为从double
到float
的每次缩小转换都是有损的,无论涉及的实际值如何。因此float myFloat = 3.0;
也会失败。但是,float myFloat = 3;
会成功,因为从int
值到float
的转换被认为是扩大转换。)
在这两种情况下,正确的做法是通过将适当的后缀附加到数字文字来向编译器准确指示您要执行的操作。
关于java - 为什么 long 和 float 数据类型末尾需要 "F"和 "L"后缀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66305194/