我正在为 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));
我认为最后要完成的操作将是结果类型,然而,这似乎不是上述示例中的情况。 (我没有列出任何与 double 相关的操作,但是,似乎 double 像 float 一样优先。)
我的另一个想法是,因为它必须进行浮点运算,所以它正在将其转换为最大的 (32/64) 位类型,这样就不会丢失任何信息,除非有一个特定的强制转换隐藏了它的事实是一个 float / double ,例如以下表达式的计算结果为长整型。
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 .粗略地说,这意味着操作数被扩大以相互兼容。
更准确地说:
- 如果一个操作数是 double ,则另一个加宽为 double
- 否则,如果一个操作数是 float ,则另一个被加宽为 float
- 否则,如果一个操作数是long,则另一个被加宽为long
- 否则,两个操作数都被扩展为 int
最后一点告诉你,即使相乘类似的类型,比如 short 和 short,操作数仍然扩大到 int
有了这两点:
l * i
是长(l * i) * f
是一个 float((l * i) * f) * s
是一个 float(((l * i) * f) * s) * b
是一个 float 。
因此,您正在从 float 转换为 int。
关于java - java如何定义算术表达式的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58365736/