java - Java 中的扩展或自动类型转换;为什么会有精度损失?
问题描述
以这段代码为例。
class Main {
public static void main(String[] args) {
int i = 41;
long l = i*9/5; //no explicit type casting required
float f = i*9/5; //no explicit type casting required
double d = i*9/5; //no explicit type casting required
double e = (double) i*9/5;
System.out.println("Int value "+i);
System.out.println("Long value "+l);
System.out.println("Float value "+f);
System.out.println("Double value "+d);
System.out.println("Double value cast "+e);
}
}
目标类型大于源类型,因此不需要显式转换,但为什么会丢失精度?为什么我不能得到d
73.8 f
?
解决方案
让我们来看看f
:float f = i*9/5;
因为乘法和除法运算符具有相同的优先级并且是左结合的,所以该语句等价于:float f = (i*9)/5;
因为i=41
和9
都是int
-typed,所以结果值的类型也是int
( 369
)。因此,评估的下一步是369/5
。因为两个操作数的类型都是int
,所以运算符的解释/
是使用整数除法,它会丢弃任何小数余数。因为369/5 = 73 + 4/5
,表达式的计算结果为73
,然后将其转换为float
值73.0
并分配给f
。
一个非常相似的过程发生了d
,除了73
is 到一个double
值的最终转换73.0
。
请注意,尽管我在评估中包括了中间步骤,但左结合性对整数除法的使用没有影响。float f = i*(9/5);
结果f = 41.0
。
推荐阅读
- javascript - Gatsby.js 默认起始站点未在 Typography.js 更改时更新
- rust - Rust 标准库的共享库和静态库在哪里?
- javascript - jQuery:如何添加具有在单击按钮时递增的动态 id 的 div?
- mongodb - 如果它是MongoDB中的字符串,如何有条件地将字段转换为日期?
- ruby-on-rails - 如何在 Ruby on Rails 中管理嵌套字段的多对多关系
- julia - Julia:基函数的意外扩展
- java - 依赖项失败的 Spring 控制器测试
- osgi - 刷新包捆绑
- windows - Robocopy 备份-/restartmodus (/Z) 不起作用
- swift - 将 Firebase 快照数组保存到 NSUserDefaults