Following the precedence operator in java 8 it is clear that the postfix operator (expr++ expr--) has a higher precedence that the unary operator, pre-unary operator (++expr --expr).
However when executing this code:
x = 3; y = ++x - x++;
The value of y is 0
But to me, following the above table, the result should be
y = (5 - 3) as x++ should be evaluated first.
Can anyone explain why this is y = 0 and not y = 2?
When do I use the Operator precedence on the same line in an expression? or why there is an operator precedence order and when is used?
Operator precedence decides which one of several operators is associated with an operand. In the expression ++x - x++ there are two places where precedence comes into play:
++x - … - The two operators ++ and (binary) - could be used on x; ++ has precedence, so this is equivalent to (++x) - …, not to ++(x - …).
… - x++ - The two operators (binary) - and ++ could be used on x; ++ has precedence, so this is equivalent to … - (x++), not to (… - x)++.
Related
The DOC explains perl operator precedence and associativity. I am interesting at -> and * operators. Both have left associativity.
I have next example and it seems that -> has right associativity. Not left as documentation states:
my #args;
sub call { print "call\n"; shift #args }
sub test { print "test\n"; 1 }
sub t4 { print "t4\n"; 4 }
#args=( \&test, 2, 3 );
call()->( #args, t4 );
sub m1 { print "m1\n"; 2 }
sub m2 { print "m2\n"; 4 }
m1()*(#args, m2);
The output is:
t4
call
test
m1
m2
Because -> has left associativity I expect next output:
call
t4
test
m1
m2
What did I miss? Why t4 is called before call?
You are asking about operand evaluation order (the order in which operands are evaluated), not operator associativity (the order in which operators of the same operator precedence are evaluated).
The operand evaluation order is undefined (or at least undocumented) for many operators, including ->. You will find it consistent, but one shouldn't rely on that.
You can use statement breaks to force the desired order:
my $sub = call();
$sub->( #args, t4 );
This would also work:
$_->( #args, t4 ) for call();
Operator Associativity
Associativity is the order in which operators of the same precedence are evaluated.
For example, * and / have the same precedence, so associativity determines that
3 / 4 * 5 * 6
is equivalent to
( ( 3 / 4 ) * 5 ) * 6 = 22.5
and not
3 / ( 4 * ( 5 * 6 ) ) = 0.025
As you can see, associativity can have a direct effect on the outcome of the expression.
Operand Evaluation Order
Operand evaluation order is the order in which operands are evaluated.
For example, operand evaluation order determines whether 1+2 is evaluated before 3+4, or vice-versa in
( 1 + 2 ) * ( 3 + 4 )
Unless evaluating the operand has a side-effect (e.g. changing a variable or printing to the screen), then operand evaluation order has no effect on the outcome of the expression. As such, some languages leave it undefined to allow for optimization.
In Perl, it's undefined (or at least undocumented) for many operators. It's only documented for the following:
The comma operator (, and =>): left to right
Binary boolean operators (and, or, &&, || and //): left, then maybe right[1]
Conditional operators (? :): left, then either second or third[1]
List and scalar assignment operators (=): right, then left[2]
Binding operators (=~ and !~): left, then right[3]
Required for short-circuited evaluation.
Required for my $x = $x;.
Required to function at all.
Associativity is a rule that tells you how to parse an expression where the same operator appears twice, or more than one operator with the same precedence level appears. For example, associativity determines that:
foo()->bar()->baz()
is equivalent to
(foo()->bar())->baz() # left associative
and not
foo()->(bar()->baz()) # right associative
Since your code only hase one -> operator in it, the associativity of that operator is irrelevant.
You seem to be looking for a rule about the order of evaluation of operands to the -> operator. As far as I know, there is no guaranteed order of evaluation for most operators in perl (much like C). If the order matters, you should split the expression into multiple statements with an explicit temporary variable:
my $tmp = call();
$tmp->( #args, t4 );
Associativity describes the order that multiple operators of equal precedence are handled. It has nothing to do with whether the left arguments or the right arguments are processed first. -> being left associative means that a->b->c is processed as (a->b)->c, not as a->(b->c).
I need to compute some fairly long expressions that contain common subexpressions. For example, consider the following two expressions:
double dfdx1 = 2 * (-x2 + x1 - sin(b2)*n34 + cos(b2)*sin(c2)*n24 - cos(b2)*cos(c2)*n14 + sin(b1)*m34 - cos(b1)*sin(c1)*m24 + cos(b1)*cos(c1)*m14);
double dfdx2 = -2 * (-x2 + x1 - sin(b2)*n34 + cos(b2)*sin(c2)*n24 - cos(b2)*cos(c2)*n14 + sin(b1)*m34 - cos(b1)*sin(c1)*m24 + cos(b1)*cos(c1)*m14);
Aside from eliminating all the trigonometric functions, one obvious elimination is dfdx2 = -dfdx1. The question is whether the compiler will recognise this. I found that using MATLAB's MuPad generate::optimize() function does not, which rather surprised me.
More generally, will the compiler recognise that f2 = -f1 in the example below:
double f1 = a*a + b*b - c*a - c*b;
double f2 = c*a + c*b - a*a - b*b;
Or will it just eliminate the terms a*a, b*b, c*a and c*b?
I am using the MSVC compiler, but I guess that they all do pretty much the same thing.
Normally compilers should recognize this and carry out the asked transformation if you enable "fast math" (-ffast-math for gcc). The reason is that floating point operations are not perfectly exact and the order of the evaluation of an expression might matter.
Example (for doubles, all constants are actually considered being results of other operations):
"1e100"+"1.0"-"1e100" results in 0.0
"1e100"-"1e100"+"1.0" results in 1.0
So the compiler will only reorder expressions if you explicitly allow such transformations.
I was thinking of making an integer power function in Swift based on this StackOverflow answer:
func **<T : IntegerType>(var base: T, var exponent: T) -> T {
var result: T = 1
assert(exponent >= 0, "Exponent cannot be negative")
while exponent > 0 {
if exponent & 1 != 0 {
result *= base
}
exponent = exponent >> 1
base *= base
}
return result
}
I figured I could use generics to implement the function so that it would work with any integer type.
Unfortunately, I get an error when I attempt to use exponent >> 1:
Binary operator '>>' cannot be applied to two 'T' operands
Checking the function definitions for >>, I see that there is one for each of the ten integer types, but no other ones are defined. I was surprised therefore that all the other operators were working, such as &, but I noticed that & was actually defined to work on all types which conform to BitwiseOperationsType, which IntegerType appears to conform to.
Is there a reason why the >> and << operators are not implemented for BitwiseOperationsType?
How can I make the exponentiation operator ** in Swift behave the same as in other programming languages.
The question Exponentiation operator in Swift has the following answer which has the highest number of up votes,
infix operator ** { associativity left precedence 170 }
func ** (num: Double, power: Double) -> Double{
return pow(num, power)
}
However, y = -x**2,
is interpreted as (-x)**2 = 4.0 (Swift)
usually it should be interpreted as -(x**2) = -4.0 (Expected!)
I believe your problem is:
Unary operators in Swift always take precedence over binary operators.
Here's the source: https://medium.com/swift-programming/facets-of-swift-part-5-custom-operators-1080bc78ccc
Therefore, the expression is always evaluated as (-x)**2 instead of -(x**2), since - is a unary operator and ** is a binary operator.
What is the difference between the | and || logical operators in MATLAB?
I'm sure you've read the documentation for the short-circuiting operators, and for the element-wise operators.
One important difference is that element-wise operators can operate on arrays whereas the short-circuiting operators apply only to scalar logical operands.
But probably the key difference is the issue of short-circuiting. For the short-circuiting operators, the expression is evaluated from left to right and as soon as the final result can be determined for sure, then remaining terms are not evaluated.
For example, consider
x = a && b
If a evaluates to false, then we know that a && b evaluates to false irrespective of what b evaluates to. So there is no need to evaluate b.
Now consider this expression:
NeedToMakeExpensiveFunctionCall && ExpensiveFunctionCall
where we imagine that ExpensiveFunctionCall takes a long time to evaluate. If we can perform some other, cheap, test that allows us to skip the call to ExpensiveFunctionCall, then we can avoid calling ExpensiveFunctionCall.
So, suppose that NeedToMakeExpensiveFunctionCall evaluates to false. In that case, because we have used short-circuiting operators, ExpensiveFunctionCall will not be called.
In contrast, if we used the element-wise operator and wrote the function like this:
NeedToMakeExpensiveFunctionCall & ExpensiveFunctionCall
then the call to ExpensiveFunctionCall would never be skipped.
In fact the MATLAB documentation, which I do hope you have read, includes an excellent example that illustrates the point very well:
x = (b ~= 0) && (a/b > 18.5)
In this case we cannot perform a/b if b is zero. Hence the test for b ~= 0. The use of the short-circuiting operator means that we avoid calculating a/b when b is zero and so avoid the run-time error that would arise. Clearly the element-wise logical operator would not be able to avoid the run-time error.
For a longer discussion of short-circuit evaluation, refer to the Wikipedia article on the subject.
Logical Operators
MATLAB offers three types of logical operators and functions:
| is Element-wise — operate on corresponding elements of logical arrays.
Example:
vector inputs A and B
A = [0 1 1 0 1];
B = [1 1 0 0 1];
A | B = 11101
|| is Short-circuit — operate on scalar, logical expressions
Example:
|| : Returns logical 1 (true) if either input, or both, evaluate to true, and logical 0 (false) if they do not.
Operand: logical expressions containing scalar values.
A || B (B is only evaluated if A is false)
A = 1;
B = 0;
C =(A || (B = 1));
B is 0 after this expression and C is 1.
Other is, Bit-wise — operate on corresponding bits of integer values or arrays.
reference link
|| is used for scalar inputs
| takes array input in if/while statements
From the source:-
Always use the && and || operators when short-circuiting is required.
Using the elementwise operators (& and |) for short-circuiting can
yield unexpected results.
Short-circuit || means, that parameters will be evaluated only if necessarily in expression.
In our example expr1 || expr2 if expr1 evaluates to TRUE, than there is no need to evaluate second operand - the result will be always TRUE. If you have a long chain of Short-circuit operators A || B || C || D and your first evaluates to true, then others won't be evaluated.
If you substitute Element-wise logical | to A | B | C | D then all elements will be evaluated regardless of previous operands.
| represents OR as a logical operator. || is also a logical operator called a short-circuit OR
The most important advantage of short-circuit operators is that you can use them to evaluate an expression only when certain conditions are satisfied. For example, you want to execute a function only if the function file resides on the current MATLAB path. Short-circuiting keeps the following code from generating an error when the file, myfun.m, cannot be found:
comp = (exist('myfun.m') == 2) && (myfun(x) >= y)
Similarly, this statement avoids attempting to divide by zero:
x = (b ~= 0) && (a/b > 18.5)
You can also use the && and || operators in if and while statements to take advantage of their short-circuiting behavior:
if (nargin >= 3) && (ischar(varargin{3}))