在Java中我打印这样的东西
System.out.println(1.0f*1l));
我得到
的输出1.0
或
System.out.println(((byte)1)*'A');
我得到
的输出65
在这两种情况下,其中一种类型比另一种更大。长整数是64位,浮点数是32位,字节是8位,而字符是16位。尽管如此,Java还是以较小的类型输出结果。这不会被视为精确度的损失吗?
答案 0 :(得分:4)
Java语言规范提供了一个基于操作数类型控制结果类型的规则列表。
特别是,第4.2.4节说
如果二元运算符的至少一个操作数是浮点类型,则操作是浮点运算,即使另一个是整数运算。
解释了为什么float
“胜出”long
。
整数算术在5.6.2节中解释。具体来说,它说
应用扩展基元转换(第5.1.2节)来转换以下规则指定的一个或两个操作数:
•如果任一操作数的类型为
double
,则另一个操作数将转换为double
。•否则,如果任一操作数的类型为
float
,则另一个操作数将转换为float
。•否则,如果任一操作数的类型为
long
,则另一个操作数将转换为long
。•否则,两个操作数都将转换为
int
类型。
这就是为什么在你的第二个例子中,结果65是类型int
。
答案 1 :(得分:0)
Java根据可能值的范围扩展类型。这意味着float
被视为比long
更宽。
同样不是long
的整数运算也作为int
执行。
byte * char
是int
答案 2 :(得分:0)
您在询问Binary Numeric Promotion (JLS 5.6.2)(强调我的):
当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示可转换为数字类型的值,以下规则适用:
表达式1.0f*1l
是float
和long
,因此long
会转换为float
。
表达式((byte)1)*'A'
是byte
和char
,因此它们都转换为int
。
答案 3 :(得分:0)
除了详细说明规则的其他答案之外,我认为还应该考虑为什么它应该是这样的。假设你做了
2.7F * 2L
这种乘法的真正数学答案是5.4。因此,如果答案是long
,那么它必须是5L
(5是最接近5.4的整数)。由于这种情况,将浮点值乘以整数作为浮点值的结果更有意义。如果下面的代码行打印5
,我认为在Stack Overflow上会有更多关于此的问题。
System.out.println(2.7F * 2L);
实际上它会打印5.4
。
整数类型(long
除外)之间的所有操作都使用int
完成。毕竟,byte
通常被认为是一小块数据,char
通常被认为是一个字符。从这些角度来看,乘以byte
或char
值并不重要。保持规则简单并使用int
进行操作更有意义。