float的快捷方式赋值和正常赋值行为

时间:2013-12-17 03:23:28

标签: java compiler-errors floating-point

我有一个简单的怀疑

float k = 0;        
k+=0.2;     
k=k+0.2; // here compliation error 

编译错误Type mismatch: cannot convert from double to float

我的问题是为什么不在k+=0.2;

编译错误

4 个答案:

答案 0 :(得分:2)

来自Java specification

  

15.26.2。复合赋值运算符

     

E1 op= E2形式的复合赋值表达式等同于E1 = (T) ((E1) op (E2)),其中TE1的类型,但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以及floatdouble的转换,那么像你这样的分配可以很好地编译,但是{{}等表达式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),这个值远大于预期的值,没有任何编译器发出任何声响。