java如何定义算术表达式的结果
how does java define the result of an arithmetic expression
我正在为 Java 编写解析器,但是,当涉及到基本类型的操作时,我有点迷茫。
例如我有这些表达式:
int i;
long l;
float f;
short s;
byte b;
//this is being cast from a float to an int? should this be a cast from byte?
int var1 = (int) (l * i * f * s * b);
//this is being cast from a float to an int? should this be a cast from long?
int var2 = (int) (l * (i * f * s * b));
//again casting from float to int? should this be a cast from short?
int var3 = (int) ((f) * (l) * (s));
//this seems to be a float but i expected this to be a long
int var4 = (int) ((f) * (l));
我认为最后要完成的操作将是结果类型,但是,这似乎不是上述示例中的情况。 (我没有列出任何双精度运算,但是,似乎双精度像浮点数一样优先。)
我的另一个想法是,因为它必须进行浮点运算,所以它正在将其转换为最大的 (32/64) 位类型,这样就不会丢失任何信息,除非有一个特定的强制转换隐藏了这一事实它 是 一个 float/double,例如以下表达式的计算结果为 long。
int var1 = (l * i * (int) d * s * b);
这种想法确实不尽如人意,但是,就好像在同一个表达式中有一个 long/float 如果 long 的值太大而无法放入 float,您可能会丢失信息.
您可以找到 in the language spec 的两个最相关的详细信息是:
乘法(以及加法、减法、除法等)是左结合。所以:
l * i * f * s * b
被评估为
(((l * i) * f) * s) * b
乘法(以及加法、减法、除法等)的操作数经过binary numeric promotion。松散地,这意味着操作数被扩大以相互兼容。
更准确地说:
- 如果一个操作数是双精度,则另一个加宽为双精度
- 否则,如果一个操作数是浮点数,则另一个被加宽为浮点数
- 否则,如果一个操作数是long,则另一个被加宽为long
- 否则,两个操作数都被扩展为 int
最后一点告诉你,即使相乘类似的类型,比如 short 和 short,操作数仍然扩大到 int
有了这两点:
l * i
是一个长
(l * i) * f
是一个浮点数
((l * i) * f) * s
是一个浮点数
(((l * i) * f) * s) * b
是一个浮点数。
因此,您正在从 float 转换为 int。
我正在为 Java 编写解析器,但是,当涉及到基本类型的操作时,我有点迷茫。
例如我有这些表达式:
int i;
long l;
float f;
short s;
byte b;
//this is being cast from a float to an int? should this be a cast from byte?
int var1 = (int) (l * i * f * s * b);
//this is being cast from a float to an int? should this be a cast from long?
int var2 = (int) (l * (i * f * s * b));
//again casting from float to int? should this be a cast from short?
int var3 = (int) ((f) * (l) * (s));
//this seems to be a float but i expected this to be a long
int var4 = (int) ((f) * (l));
我认为最后要完成的操作将是结果类型,但是,这似乎不是上述示例中的情况。 (我没有列出任何双精度运算,但是,似乎双精度像浮点数一样优先。)
我的另一个想法是,因为它必须进行浮点运算,所以它正在将其转换为最大的 (32/64) 位类型,这样就不会丢失任何信息,除非有一个特定的强制转换隐藏了这一事实它 是 一个 float/double,例如以下表达式的计算结果为 long。
int var1 = (l * i * (int) d * s * b);
这种想法确实不尽如人意,但是,就好像在同一个表达式中有一个 long/float 如果 long 的值太大而无法放入 float,您可能会丢失信息.
您可以找到 in the language spec 的两个最相关的详细信息是:
乘法(以及加法、减法、除法等)是左结合。所以:
l * i * f * s * b
被评估为
(((l * i) * f) * s) * b
乘法(以及加法、减法、除法等)的操作数经过binary numeric promotion。松散地,这意味着操作数被扩大以相互兼容。
更准确地说:
- 如果一个操作数是双精度,则另一个加宽为双精度
- 否则,如果一个操作数是浮点数,则另一个被加宽为浮点数
- 否则,如果一个操作数是long,则另一个被加宽为long
- 否则,两个操作数都被扩展为 int
最后一点告诉你,即使相乘类似的类型,比如 short 和 short,操作数仍然扩大到 int
有了这两点:
l * i
是一个长(l * i) * f
是一个浮点数((l * i) * f) * s
是一个浮点数(((l * i) * f) * s) * b
是一个浮点数。
因此,您正在从 float 转换为 int。