我有一个简单的怀疑
float k = 0;
k+=0.2;
k=k+0.2; // here compliation error
编译错误Type mismatch: cannot convert from double to float
我的问题是为什么不在k+=0.2;
答案 0 :(得分:2)
15.26.2。复合赋值运算符
E1 op= E2
形式的复合赋值表达式等同于E1 = (T) ((E1) op (E2))
,其中T
是E1
的类型,但E1
仅被评估一次。
因此+=
运算符具有对目标类型的内置强制转换。
相比之下,clause for simple assignment says:
15.26.1。简单分配操作符=
如果右侧操作数的类型无法通过赋值转换(第5.2节)转换为变量类型,则会发生编译时错误。
Clause 5.2允许扩大转化次数,但不允许缩小转化次数。因此,在k+.2
中,常量.2
具有类型double
,这会导致表达式具有类型double
,而double
表达式可能不会直接分配给float
个对象;它需要一个明确的演员。
答案 1 :(得分:1)
在Java中,默认十进制数视为double。
您需要在数字末尾添加“f
”或“F
”的浮点数,例如k=k+0.2f;
或k=k+0.2F;
答案 2 :(得分:1)
Java假定文字十进制值是双精度数。你需要在值后面明确地加上“f”或“F”来强制它成为一个浮点数。
答案 3 :(得分:0)
如果Java允许从double
扩展到float
以及float
到double
的转换,那么像你这样的分配可以很好地编译,但是{{}等表达式1}}会模棱两可。为了避免这种歧义,Java按顺序查看所有原始类型,以便每种类型可以转换为下一个更高类型,但反之亦然。尽管表示编程错误的隐式float-to-double转换的百分比远远超过了隐含的double-to-float转换的百分比(*),但是希望将类型排列成严格的序列,同时避免使用{{ 1}}翻译为someFloat == someDouble
动机类型转换规则,允许在没有类型转换的情况下完成更可能没有错误的构造,同时在没有它们的情况下行为明显的情况下需要类型转换。
在您的演员表中,如果您通过添加someFloat == someDouble
后缀指定常量是someFloat == (float)someDouble
而不是float
,编译器可能不会发出尖叫声,否则避免使用double
并简单地使用f
。我通常会建议后一种方法。如果您使用float
并稍后将变量更改为double
类型,那么您的数学将被编译正常但会产生错误结果,除非您从常量中删除后缀(并且还删除任何显式类型转换为{{1像函数返回值这样的东西)。像float
这样的语句会将double
设置为精确地等于13421773/134217728(即0.100000001490116),这个值远大于预期的值,没有任何编译器发出任何声响。