Java如何处理多种类型的精度?

时间:2016-03-27 16:25:16

标签: java precision primitive-types

在Java中我打印这样的东西

System.out.println(1.0f*1l));

我得到

的输出
1.0

System.out.println(((byte)1)*'A');

我得到

的输出
65

在这两种情况下,其中一种类型比另一种更大。长整数是64位,浮点数是32位,字节是8位,而字符是16位。尽管如此,Java还是以较小的类型输出结果。这不会被视为精确度的损失吗?

4 个答案:

答案 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 * charint

答案 2 :(得分:0)

您在询问Binary Numeric Promotion (JLS 5.6.2)(强调我的):

  

当运算符将二进制数字提升应用于一对操作数时,每个操作数必须表示可转换为数字类型的值,以下规则适用:

     
      
  1. 如果任何操作数属于引用类型,则会进行拆箱转换(§5.1.8)。
  2.   
  3. 扩展基元转换(§5.1.2)用于转换以下规则指定的一个或两个操作数:      
        
    • 如果任一操作数的类型为double,则另一个操作数将转换为double
    •   
    • 否则,如果任一操作数的类型为float,则另一个操作数将转换为float
    •   
    • 否则,如果任一操作数的类型为long,则另一个操作数将转换为long
    •   
    • 否则,两个操作数都将转换为int 类型。
    •   
  4.   

表达式1.0f*1lfloatlong,因此long会转换为float

表达式((byte)1)*'A'bytechar,因此它们都转换为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通常被认为是一个字符。从这些角度来看,乘以bytechar值并不重要。保持规则简单并使用int进行操作更有意义。