java如何定义算术表达式的结果
我正在为Java编写一个解析器,但是,当涉及到对基本类型的操作时,我有点不知所措 例如,我有以下表达式:java如何定义算术表达式的结果,java,arithmetic-expressions,Java,Arithmetic Expressions,我正在为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 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)位类型,这样就不会丢失任何信息,除非有一个特定的强制转换隐藏了它是浮点/双精度的事实,例如,下面的表达式的计算结果为long
int var1 = (l * i * (int) d * s * b);
但是,这种想法确实有不足之处,就像同一表达式中存在long/float一样,如果long的值太大而无法放入float中,您可能会丢失信息。您可以找到的两个最相关的细节是:
- 乘法(以及加法、减法、除法等)是左联想的。因此:
被评估为
(((l * i) * f) * s) * b
- 乘法(和加法、减法、除法等)的操作数要经过运算。松散地说,这意味着操作数被加宽以彼此兼容
更准确地说:
- 如果一个操作数为双精度,则另一个操作数将加宽为双精度
- 否则,如果一个操作数是浮点,则另一个操作数将加宽为浮点
- 否则,如果一个操作数为长操作数,则另一个操作数将加宽为长操作数
- 否则,两个操作数都将加宽为int
是一个很长的l*i
是一个浮点数(l*i)*f
是一个浮点数((l*i)*f)*s
是浮点数(((l*i)*f)*s)*b
因此,您正在从浮点到int进行施法。这是一个Antlr。这里是的java参考。“只要你不计算表达式,你就不用为它操心了。@curiosa这只是一个语法,如果我错了,请纠正我,但它没有显示与运算顺序有关的任何内容,也没有显示生成的原始运算类型。你看过吗?”?
(((l * i) * f) * s) * b