需要帮助理解为什么这段代码不能编译
Need help on understanding why this code doesn't compile
What is the data type of x + y?
double x = 39.21;
float y = 2.1;
Explanation:
This is actually a trick question, as this code will not compile! As
you may remember from Chapter 1, floating-point literals are assumed
to be double, unless postfixed with an f, as in 2.1f. If the value was
set properly to 2.1f, then the promotion would be similar to the last
example, with both operands being promoted to a double, and the result
would be a double value.
But I don't understand. If float y = 2.1; was assumed to be double
there would be no need for the promotion of variable y to the double.
And I'm more confused by the next problem, which is:
What is the data type of x * y / z?
short x = 14; float y = 13; double z = 30;
书上说这甚至可以编译 float y = 13;不是浮动 y = 13f。如果它们是十进制的,我是否只在浮点数旁边添加 f?我真的看不出这个问题和上述问题之间的区别。
对于第一个问题,您不能将浮点数(具有双精度值)初始化为双精度值。使用 2.1f
将该值初始化为浮点数。所以你需要 y = 2.1f
。您可以阅读更多相关信息 here
对于第二个问题,之所以可行,是因为 float 是一个整数 (13),可以提升为 float 类型。
如本post所述,如果您不在数字后指定字符'f',则该值将被视为双精度值。
话虽如此,下面的代码片段将编译,但前提是将字符 'f' 添加到浮点值的末尾。
double x = 7.0;
float y = 2.0f;
System.out.print(x + y);
忽略 char
、Java 将 提升 数字类型,如下所示:
byte > short > int > long > float > double
这些称为扩大转化。有关详细信息,请参阅 JLS §5.1.2. Widening Primitive Conversion。
二元运算符将提升为 int
、long
、float
或 double
,取最接近运算符两个值的那个,即结果永远不会是 byte
或 short
。示例:byte + short
会将双方提升为 int
。有关详细信息,请参阅 JLS §5.6.2. Binary Numeric Promotion。
赋值运算符还将对值进行加宽转换,额外的规则是常量表达式 [=20] =]、short
或 int
将通过 narrowing conversion if the type of the variable is byte
or short
, and the value of the constant expression is representable in the type. Note, there is no rule for narrowing double
constant to float
. See JLS §5.2. Assignment Contexts 获取详细信息。
因此,对于您的代码:
double x = 39.21; // double constant to double (identity conversion)
float y = 2.1; // fails because double constant cannot promote to float
如果代码编译成功,x + y
的数据类型是什么?
x + y // double + float promotes to double
答案:double
下一部分:
short x = 14; // narrowing conversion of int constant to short
float y = 13; // widening conversion of int constant to float
double z = 30; // widening conversion of int constant to double
现在,x * y / z
的数据类型是什么?
x * y // short * float promotes to float
(x * y) / z // (float) / double promotes to double
答案:double
What is the data type of x + y?
double x = 39.21;
float y = 2.1;
Explanation:
This is actually a trick question, as this code will not compile! As you may remember from Chapter 1, floating-point literals are assumed to be double, unless postfixed with an f, as in 2.1f. If the value was set properly to 2.1f, then the promotion would be similar to the last example, with both operands being promoted to a double, and the result would be a double value.
But I don't understand. If float y = 2.1; was assumed to be double there would be no need for the promotion of variable y to the double. And I'm more confused by the next problem, which is:
What is the data type of x * y / z?
short x = 14; float y = 13; double z = 30;
书上说这甚至可以编译 float y = 13;不是浮动 y = 13f。如果它们是十进制的,我是否只在浮点数旁边添加 f?我真的看不出这个问题和上述问题之间的区别。
对于第一个问题,您不能将浮点数(具有双精度值)初始化为双精度值。使用 2.1f
将该值初始化为浮点数。所以你需要 y = 2.1f
。您可以阅读更多相关信息 here
对于第二个问题,之所以可行,是因为 float 是一个整数 (13),可以提升为 float 类型。
如本post所述,如果您不在数字后指定字符'f',则该值将被视为双精度值。
话虽如此,下面的代码片段将编译,但前提是将字符 'f' 添加到浮点值的末尾。
double x = 7.0;
float y = 2.0f;
System.out.print(x + y);
忽略 char
、Java 将 提升 数字类型,如下所示:
byte > short > int > long > float > double
这些称为扩大转化。有关详细信息,请参阅 JLS §5.1.2. Widening Primitive Conversion。
二元运算符将提升为 int
、long
、float
或 double
,取最接近运算符两个值的那个,即结果永远不会是 byte
或 short
。示例:byte + short
会将双方提升为 int
。有关详细信息,请参阅 JLS §5.6.2. Binary Numeric Promotion。
赋值运算符还将对值进行加宽转换,额外的规则是常量表达式 [=20] =]、short
或 int
将通过 narrowing conversion if the type of the variable is byte
or short
, and the value of the constant expression is representable in the type. Note, there is no rule for narrowing double
constant to float
. See JLS §5.2. Assignment Contexts 获取详细信息。
因此,对于您的代码:
double x = 39.21; // double constant to double (identity conversion)
float y = 2.1; // fails because double constant cannot promote to float
如果代码编译成功,x + y
的数据类型是什么?
x + y // double + float promotes to double
答案:double
下一部分:
short x = 14; // narrowing conversion of int constant to short
float y = 13; // widening conversion of int constant to float
double z = 30; // widening conversion of int constant to double
现在,x * y / z
的数据类型是什么?
x * y // short * float promotes to float
(x * y) / z // (float) / double promotes to double
答案:double