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

Java如何跨多种类型处理精度?,java,precision,primitive-types,Java,Precision,Primitive Types,在Java中,当我打印这样的内容时 System.out.println(1.0f*1l)); 我得到的输出是 1.0 65 或与 System.out.println(((byte)1)*'A'); 我得到的输出是 1.0 65 在这两种情况下,其中一种比另一种大。long是64位,float是32位,bytes是8位,chars是16位。尽管如此,Java还是以较小的类型输出结果。这难道不被认为是精度的损失吗?Java根据可能值的范围扩展了类型。这意味着float被认为比long

在Java中,当我打印这样的内容时

System.out.println(1.0f*1l));
我得到的输出是

1.0
65
或与

System.out.println(((byte)1)*'A');
我得到的输出是

1.0
65

在这两种情况下,其中一种比另一种大。long是64位,float是32位,bytes是8位,chars是16位。尽管如此,Java还是以较小的类型输出结果。这难道不被认为是精度的损失吗?

Java根据可能值的范围扩展了类型。这意味着
float
被认为比
long
更宽

另外,不长的整数运算作为
int
执行。
byte*char
是一种
int

Java根据可能值的范围扩展类型。这意味着
float
被认为比
long
更宽

另外,不长的整数运算作为
int
执行。
byte*char
是一种
int

Java语言规范提供了基于操作数类型的结果类型规则列表

特别是,第4.2.4节规定

如果二进制运算符的操作数中至少有一个是浮点类型的,则该运算是浮点运算,即使另一个是整数

这解释了为什么
float
“赢”了
long

第5.6.2节解释了整数运算。具体来说,它说

加宽基元转换(§5.1.2)用于转换以下规则指定的一个或两个操作数:

•如果任一操作数的类型为
double
,则另一个操作数将转换为
double

•否则,如果任一操作数的类型为
浮点
,则另一个操作数将转换为
浮点

•否则,如果任一操作数的类型为
long
,则另一个操作数将转换为
long

•否则,两个操作数都将转换为类型
int


这就是为什么在第二个示例中,结果65的类型为
int

Java语言规范提供了一个基于操作数类型的结果类型规则列表

特别是,第4.2.4节规定

如果二进制运算符的操作数中至少有一个是浮点类型的,则该运算是浮点运算,即使另一个是整数

这解释了为什么
float
“赢”了
long

第5.6.2节解释了整数运算。具体来说,它说

加宽基元转换(§5.1.2)用于转换以下规则指定的一个或两个操作数:

•如果任一操作数的类型为
double
,则另一个操作数将转换为
double

•否则,如果任一操作数的类型为
浮点
,则另一个操作数将转换为
浮点

•否则,如果任一操作数的类型为
long
,则另一个操作数将转换为
long

•否则,两个操作数都将转换为类型
int

这就是为什么在您的第二个示例中,结果65是您要询问的类型
int

(强调我的):

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

  • 如果任何操作数属于引用类型,则将对其进行取消装箱转换()
  • 加宽基元转换()用于转换以下规则指定的一个或两个操作数:
    • 如果任一操作数的类型为
      double
      ,则另一个操作数将转换为
      double
    • 否则,如果其中一个操作数的类型为
      float
      ,则另一个操作数将转换为
      float
    • 否则,如果任一操作数的类型为
      long
      ,则另一个操作数将转换为
      long
    • 否则,两个操作数都转换为类型
      int
  • 表达式
    1.0f*1l
    float
    long
    ,因此
    long
    转换为
    float

    表达式
    ((byte)1)*'A'
    字节
    字符
    ,因此它们都被转换为
    int
    (我的重点):

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

  • 如果任何操作数属于引用类型,则将对其进行取消装箱转换()
  • 加宽基元转换()用于转换以下规则指定的一个或两个操作数:
    • 如果任一操作数的类型为
      double
      ,则另一个操作数将转换为
      double
    • 否则,如果其中一个操作数的类型为
      float
      ,则另一个操作数将转换为
      float
    • 否则,如果任一操作数的类型为
      long
      ,则另一个操作数将转换为
      long
    • 否则,两个操作数都转换为类型
      int
  • 表达式
    1.0f*1l
    float
    long
    ,因此
    long
    转换为
    float


    表达式
    ((byte)1)*'A'
    字节
    字符
    ,因此它们都被转换为
    int
    ,除了其他详细说明规则的答案外,我认为还值得考虑为什么应该这样。如果你愿意的话

    2.7F * 2L
    
    这个乘法的真正数学答案是5.4。因此