java 数学表达式的正确优先级是什么
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4023673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the right precedence of the math expression
提问by bancer
What is the correct sequence of the math operations in this expression in Java:
Java 中此表达式中数学运算的正确顺序是什么:
a + b * c / ( d - e )
1. 4 1 3 2
2. 4 2 3 1
I understand that result is the same in both answers. But I would like to fully understand the java compiler logic. What is executed first in this example - multiplication or the expression in parentheses? A link to the documentation that covers that would be helpful.
我知道这两个答案的结果是一样的。但我想完全理解java编译器逻辑。在这个例子中首先执行的是乘法还是括号中的表达式?指向文档的链接会很有帮助。
UPDATE: Thank you guys for the answers. Most of you write that the expression in parentheses is evaluated first. After looking at the references provided by Grodriguez I created little tests:
更新:谢谢你们的答案。你们中的大多数人写到括号中的表达式首先被评估。在查看了 Grodriguez 提供的参考资料后,我创建了一些小测试:
int i = 2;
System.out.println(i * (i=3)); // prints '6'
int j = 2;
System.out.println((j=3) * j); // prints '9'
Could anybody explain why these tests produce different results? If the expression in parentheses is evaluated the first I would expect the same result - 9.
谁能解释为什么这些测试会产生不同的结果?如果括号中的表达式首先计算,我希望得到相同的结果 - 9。
采纳答案by JeremyP
Almost everybody so far has confused order of evaluation with operator precedence. In Java the precedence rules make the expression equivalent to the following:
到目前为止,几乎每个人都将评估顺序与运算符优先级混淆了。在 Java 中,优先规则使表达式等效于以下内容:
a + (b * c) / ( d - e )
because *
and /
have equal precedence and are left associative.
因为*
和/
具有相同的优先级并且是左结合的。
The order of evaluation is strictly defined as left hand operand first, then right, then operation(except for || and &&). So the order of evaluation is:
求值顺序严格定义为先左操作数,然后是右操作数,然后是操作数( || 和 && 除外)。所以评估的顺序是:
a
b
c
*
d
e
-
/
+
order of evaluation goes down the page. Indentation reflects the structure of the syntax tree
评估顺序在页面下方。缩进反映了语法树的结构
Edit
编辑
In response to Grodriguez's comments. The following program:
回应 Grodriguez 的评论。以下程序:
public class Precedence
{
private static int a()
{
System.out.println("a");
return 1;
}
private static int b()
{
System.out.println("b");
return 2;
}
private static int c()
{
System.out.println("c");
return 3;
}
private static int d()
{
System.out.println("d");
return 4;
}
private static int e()
{
System.out.println("e");
return 5;
}
public static void main(String[] args)
{
int x = a() + b() * c() / (d() - e());
System.out.println(x);
}
}
Produces the output
产生输出
a
b
c
d
e
-5
which clearly shows the multiplication is performed beforethe subtraction.
这清楚地表明乘法是在减法之前执行的。
回答by Grodriguez
As JeremyP has nicely shown us, the first answer is correct.
正如 JeremyP 很好地向我们展示的那样,第一个答案是正确的。
In general, the following rules apply:
一般而言,以下规则适用:
- Every operand of an operator is evaluated before the operation itself is performed (except for
||
,&&
, and?
:
) - Operands are evaluated left to right. The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.
- The order of evaluation respects parentheses and operator precedence:
- Parentheses are evaluated first.
- Operators are evaluated in order of precedence.
- Operators with equal precedence are evaluated left-to-right, except for assignment operators which are evaluated right-to-left.
- 运算符的每个操作数都会在操作本身执行之前进行评估(除了
||
、&&
、 和?
:
) - 操作数从左到右计算。二元运算符的左侧操作数似乎在评估右侧操作数的任何部分之前已完全评估。
- 计算顺序尊重括号和运算符优先级:
- 首先评估括号。
- 运算符按优先顺序计算。
- 具有相同优先级的运算符从左到右计算,除了从右到左计算的赋值运算符。
Note that the first two rules explain the result in your second question:
请注意,前两条规则解释了第二个问题中的结果:
int i = 2;
System.out.println(i * (i=3)); // prints '6'
int j = 2;
System.out.println((j=3) * j); // prints '9'
Reference documentation:
参考文档:
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#4779
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#4779
Tutorial:
教程:
http://download.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
http://download.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
回答by ILMTitan
It evaluates the expressions in the following order. Variable names are expressions that need to be evaluated.
它按以下顺序计算表达式。变量名是需要计算的表达式。
a + b * c / (d - e)
2 3 5 6
4 7
1 8
9
So, the answer to your question is #1. The order of operations determines the shape of the expression tree (what is the left side of the tree, and what is the right), but the left side is always evaluated first (and the root is evaluated last).
所以,你的问题的答案是#1。操作的顺序决定了表达式树的形状(树的左边是什么,右边是什么),但总是先评估左边(最后评估根)。
回答by Chris
I would imagine that it might evaluate something like this evaluating from left to right.
我想它可能会从左到右评估这样的评估。
a+b*c/(d-e)
a+b*c/(de)
Action Left Value Right Value
Start Add a b*c/(d-e)
Start Multiply b c
Calc Multiply (since it can)
Start Divide b*c (d-e)
Start Subtract d e
Calc Subtract
Calc Divide
Calc Add
This can be thought of as creating a binary tree representing the calculations and then working from the leaf nodes, left to right, calculating things. Unfortunately my ascii art isn't great but here's an attempt at representing the tree in question:
这可以被认为是创建一个表示计算的二叉树,然后从叶节点从左到右计算事物。不幸的是,我的 ascii 艺术不是很好,但这是代表有问题的树的尝试:
Add
/\
/ \
a \
Divide
/ \
/ \
/ \
/ \
Multiply Subtract
/\ /\
/ \ / \
b c d e
And I did some tests in C# (I know its not the same but that's where my interests lie and the tests can be easily adapted) as follows:
我在 C# 中做了一些测试(我知道它不一样,但这就是我的兴趣所在,测试可以很容易地适应)如下:
f = 1;
Console.WriteLine((f=2) + (f) * (f) / ((f) - (f)-1));
Console.WriteLine(2 + 2 * 2 / (2 - 2 - 1));
f = 1;
Console.WriteLine((f) + (f=2) * (f) / ((f) - (f)-1));
Console.WriteLine(1 + 2 * 2 / (2 - 2 - 1));
f = 1;
Console.WriteLine((f) + (f) * (f = 2) / ((f) - (f)-1));
Console.WriteLine(1 + 1 * 2 / (2 - 2 - 1));
f = 1;
Console.WriteLine((f) + (f) * (f) / ((f=2) - (f)-1));
Console.WriteLine(1 + 1 * 1 / (2 - 2 - 1));
f = 1;
Console.WriteLine((f) + (f) * (f) / ((f) - (f=2)-1));
Console.WriteLine(1d + 1d * 1d / (1d - 2d - 1d));
The pairs of console.writeline statements are the algebraic one (using the set a number trick) and a numerical representation showing what the calculation actually does. The pairs produce the same result as each other.
成对的 console.writeline 语句是代数语句(使用 set a number 技巧)和显示计算实际执行的数字表示。这些对产生彼此相同的结果。
As can be seen the arguments are evaluated in order with any after the assignment being 2 and those before being one. So the order of evaluation of things is simple left to right I think but the order of calculations is as you would expect it to be.
可以看出,参数是按顺序评估的,赋值之后的任何为 2,赋值之前的为 1。因此,我认为事物的评估顺序很简单,从左到右,但计算顺序与您期望的一样。
I assume this can be run almost with copy and paste to test in JAVA...
我认为这几乎可以通过复制和粘贴来运行以在 JAVA 中进行测试...
There may be some unnoticed assumptions in here so if anybody does spot logic flaws in here please do call me on them and I'll work them through.
这里可能有一些未被注意的假设,所以如果有人在这里发现逻辑缺陷,请给我打电话,我会解决它们。
回答by agross
In your second question, it seems Java is evaluating the part in parenthesis as an assignment, not an mathematical expression. This means that is will not perform parenthetical assignments in the same order as operations in parenthesis.
在您的第二个问题中,Java 似乎将括号中的部分作为赋值而不是数学表达式进行评估。这意味着它不会以与括号中的操作相同的顺序执行括号赋值。
回答by Amrish
i am assuming that your expression would be something like
我假设你的表情会像
x = a + b * c / ( d - e )
x = a + b * c / ( d - e )
the equality operator has right to left order of evaluation. so the expression on the right of = will be evaluated first.
相等运算符具有从右到左的评估顺序。所以 = 右边的表达式将首先被评估。
if your refer this precedence chart: http://www.java-tips.org/java-se-tips/java.lang/what-is-java-operator-precedence.html
如果您参考此优先级图表:http: //www.java-tips.org/java-se-tips/java.lang/what-is-java-operator-precedence.html
1) the brackets will be evaluated (d-e), lets say (d - e) = f so the expression then becomes x = a + b * c / f.
1) 括号将被评估 (de),让我们说 (d - e) = f 所以表达式变成 x = a + b * c / f。
2) Now * and / have same precedence, but the order of evaluation is left to right to * will be evaluated first so lets say b * c = g, so the expression becomes x = a + g /f
2) 现在 * 和 / 具有相同的优先级,但从左到右到 * 的评估顺序将首先评估,所以假设 b * c = g,所以表达式变为 x = a + g /f
3) Now / has the next precedence so g / f will be evaluated to lets say h so the expression will be come x = a + h,
3) 现在 / 具有下一个优先级,所以 g / f 将被评估为让我们说 h 所以表达式将是 x = a + h,
4) lastly evaluating a + h
4) 最后评估 a + h
回答by DJClayworth
The results of the calculation are defined by the Operator Order of Precedence. So parentheses have highest precedence here, multiplication and division next highest, and addition and subtraction lowest. Operators with equal precedence are evaluated left to right. So the expression in the question is equivalent to:
计算结果由Operator Order of Precedence定义。所以括号在这里的优先级最高,乘法和除法次高,加法和减法最低。具有相同优先级的运算符从左到右求值。所以问题中的表达式等价于:
a + (b * c) / ( d - e ))
However there is a slight difference between what is normally meant by "being evaluated first" and the operator precedence for getting the correct answer.
然而,“首先被评估”的通常含义与获得正确答案的运算符优先级之间存在细微差别。
"d-e" is not necessarily actually calculated before "a" is calculated. This pretty much doesn't make any difference unless one of the 'variables' in the expression is actually a function. The Java standard does not specify the order of evaluation of components of an expression.
在计算“a”之前,不一定要实际计算“de”。这几乎没有任何区别,除非表达式中的“变量”之一实际上是一个函数。Java 标准没有指定表达式组件的求值顺序。
回答by Edgar Bonet
a + b * c / ( d - e )
1 1
2
3
The whole point of operator precedence is to convert the expression into a syntax tree. Here the *
and -
are at the same level of the tree. Which one is evaluated first is irrelevant for the result and not warrantied.
运算符优先级的全部意义在于将表达式转换为语法树。这里*
和-
位于树的同一级别。先评估哪一个与结果无关,也不作保证。
Edit: Sorry, I got confused by my C background. As others have pointed out, Java has an "Evaluate Left-Hand Operand First" rule. Applying this rule to /
tells you that *
is evaluated first (your first answer).
编辑:对不起,我对我的 C 背景感到困惑。正如其他人指出的那样,Java 有一个“首先评估左手操作数”的规则。将此规则应用于/
告诉您*
首先评估(您的第一个答案)。