Java如何跨多种类型处理精度?
在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
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。因此