Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java如何定义算术表达式的结果_Java_Arithmetic Expressions - Fatal编程技术网

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

我正在为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)位类型,这样就不会丢失任何信息,除非有一个特定的强制转换隐藏了它是浮点/双精度的事实,例如,下面的表达式的计算结果为long

int var1 = (l * i * (int) d * s * b);

但是,这种想法确实有不足之处,就像同一表达式中存在long/float一样,如果long的值太大而无法放入float中,您可能会丢失信息。

您可以找到的两个最相关的细节是:

  • 乘法(以及加法、减法、除法等)是左联想的。因此:

    被评估为

    (((l * i) * f) * s) * b
    
  • 乘法(和加法、减法、除法等)的操作数要经过运算。松散地说,这意味着操作数被加宽以彼此兼容

    更准确地说:

    • 如果一个操作数为双精度,则另一个操作数将加宽为双精度
    • 否则,如果一个操作数是浮点,则另一个操作数将加宽为浮点
    • 否则,如果一个操作数为长操作数,则另一个操作数将加宽为长操作数
    • 否则,两个操作数都将加宽为int
    最后一点告诉您,即使将类似类型(例如short和short)相乘,操作数仍然会加宽到int

有两点:

  • l*i
    是一个很长的
  • (l*i)*f
    是一个浮点数
  • ((l*i)*f)*s
    是一个浮点数
  • (((l*i)*f)*s)*b
    是浮点数

因此,您正在从浮点到int进行施法。

这是一个Antlr。这里是的java参考。“只要你不计算表达式,你就不用为它操心了。@curiosa这只是一个语法,如果我错了,请纠正我,但它没有显示与运算顺序有关的任何内容,也没有显示生成的原始运算类型。你看过吗?”?
(((l * i) * f) * s) * b