How compilers evaluate mathematical expressions? - java

I was reading this question and then I made the following.
a = b + (c - (b = c)) + (a - (c = a))
I tried that in C and Java. It works with java , but not C.
Of course, it depends on how the compiler evaluate such expressions and after googling about that, I failed to find the answer.

The reason why it doesn't work in C is because C doesn't specify exactly when the c = a will occur. It can occur before or after the two other times it is referenced in that statement.
So depending on when the compiler decides to perform the assignment c = a, the value of the expression will vary. It's not defined.
i.e. If b = c is evaluated before c = a then, b will take the original value of c. If it is evaluated after, then it will take the value of a.

You can refer the java expressions document for the perfect answer.

Related

Add quadratic penalty term to objective function in cplex (Java)

I'm developing an Optimization tool for a domestic energy system that also contains a battery. All values are correct and the solution makes sense. The problem is that the solution contains very strong fluctuations. Meaning that the decision variable is often either 0 or the maximum value. In order to avoid that I would like to add a quadratic constraint that penalizes the difference of two values (something like the derivative). Should look something like this:
((x[t] - x[t-1]) / stepsize) ^ 2
Where x is the decision variable of interest. E.g. power_g_h[t].
My objective function (so far) ist definded as follows:
IloLQNumExpr expr = model.lqNumExpr();
for (int t = 0; t < timesteps; t++) {
expr.addTerm(problem.getCosts().getElectricityCosts(t), power_g_h[t]);
expr.addTerm(problem.getCosts().getElectricityCosts(t), power_g_b[t]);
expr.addTerm(problem.getCosts().getElectricityCosts(t), power_g_bev[t]);
expr.addTerm(problem.getCosts().getFeedCompensation(), power_pv_g[t]);
}
I hope this was somewhat understandable and someone is able to tell whether or not this is even possible in CPLEX.
If this is not possible, I would be very happy about hints on how to "smoothen" a solution in CPLEX.
With kind regards,
L.
The problem was solved as follows:
It does not seem to be possible to add an expression like x * ((a - b) ^ 2). Instead the solution was to write the above as x*a*a - 2x*a*b + x*b*b. Where x is the penalty factor and a & b are the decision variables. This way it was possible to add the term to the objective function in cplex. In code it looks something like this:
IloCplex model = new IloCplex();
...
IloLQNumExpr expr = model.lqNumExpr();
expr.addTerm(x, a, a);
expr.addTerm(x, b, b);
expr.addTerm(-2 * x, a, b);
In my case a and b was the same variable for two consecutive timestep, s.t. the change over time was kept small.

Why or condition is working differently compare with Java and SQL

In Java,
int a = 10, b = 10;
if (a == 10 || b==10)
{
// first condition (a==10) is true, so it wont check further
}
But, in SQL,
select * from my table where a = 10 or b = 10;
--As per my understanding, It should return data only based on a.
--But it returns both entries.
Why is that?
You are describing early termination - this means the second statement is only executed if the answer isn't already known, but it doesn't change the outcome (unless you execute an expression in the second statement).
So a == 10 || b == 10 will result in anything where a, or b is 10 - or where a and b are 10. Or more precisely...
a = 10
b = 10
Or
a = 10
b = 0
Or
a = 0
b = 10
If a happens to be 10, you don't really need to check b - but some languages still do.
This is not a great comparison to make. However, it's not necessarily working any different. If you were to add
if (a == 10 || b==10)
{
// first condition (a==10) is true, so it wont check further
// return a or b
}
It would return every time where a or b is 10. Pretty much the same logic behind the SQL statement.
The problem is with how you're misinterpreting WHERE, this will in fact return every record where a or b is 10.
The difference is that in Java we are checking for a conditional logic and not aggregation like SQL is doing.
Java does short-circuiting meaning that if the first operand checked is true, it will not do the other operands.
In SQL the WHERE statements is looking for all a conditions and b conditions independently since you are using or
--As per my understanding, It should return data only based on a.
Your understanding is incorrect. The query is internally optimized and you do not know what it is checking for first. But it will check either condition, and then the other if necessary in order for it to be true.
SQL does not short-circuit logical expressions. When you ask for records WHERE A = 10 OR B = 10 you are asking for both - you're not asking for ones where the first case has been satisfied.
If you are wanting to emulate that short-circuit select logic, you can use this instead:
Select *
From Table
Where A = 10
Or
(
A <> 10
And B = 10
)

Java assignment operator behavior vs C++

This occured while I was tackling a 'Cracking the Coding interview' question:
Write a function to swap a number in place (that is, without temporary variables)
I decided to write up my solution in Java (because I plan on using Java in my internship interviews.)
I came up with a solution that I was almost confident was the right answer (because I did it in one line):
public static void main(String args[]) {
int a = 5;
int b = 7;
a = b - a + (b = a);
System.out.println("a: " + a + " b: " + b);
}
Surely enough, this code executes the desired result. a == 7 and b == 5.
Now here's the funny part.
This code won't run in C++ nor is this solution in the back of the book.
So my question is: Why exactly does my solution work? I am assuming Java does things differently than other languages?
Looks at the Java Language Specification, section 15.7 (Evaluation Order):
The Java programming language guarantees that the operands of
operators appear to be evaluated in a specific evaluation order,
namely, from left to right.
So in Java the evaluation order is well-defined and does what you expect.
The C++ specification doesn't provide such a guarantee; in fact it's Undefined Behavior so the program could literally do anything.
Quoting from the cppreference, noting that no sequencing rule exists for sequencing operands to arithmetic operators:
If a side effect on a scalar object is unsequenced relative to a value
computation using the value of the same scalar object, the behavior is
undefined.

Java assignment operator

The following blockquote is taken from http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-137265.html
Do not use the assignment operator in a place where it can be easily confused with the equality operator. Example:
if (c++ = d++) { // AVOID! (Java disallows)
...
}
should be written as
if ((c++ = d++) != 0) {
...
}
I am confused by the line
if ((c++ = d++) != 0) {
Any clarification on this would be appreciated.
At the very beginning of the page I can see -
This page is not being actively maintained. Links within the documentation may not work and the information itself may no longer be valid. The last revision to this document was made on April 20, 1999
if ((c++ = d++) != 0) {
//logic
}
Syntax is not even valid (Using Java6). It gives me
The left-hand side of an assignment must be a variable
You need to assign c++ to some variable.
In contrast with other languages like C, Java's scalar primitives (integers, etc.) cannot be used as booleans. In other words, 0 is in no sense either true or false. Only whether something is equal to 0 can be true or false.
They're just trying to say that the compiler requires the condition of an if statement to evaluate to a boolean value. If you know what you're doing, and decide to put actual code with side effects as the condition, you're required to make the expression evaluate to a value of type boolean.
Whereas the anti-pattern code in the example would work out in a programming language like C where boolean values are actually integers (where zero is false, and non-zero is true), the proper way to do this in Java is to actually compare the result to 0.
(c++ = d++) is an integer expression, not a boolean expression. It evaluates to whatever integer c got assigned to in the c++ = d++ assignment. Hence if (c++ = d++) { is a non starter in java.
So the comparison with 0 is what it takes to convert the integer expression to boolean.
And I think it goes without saying. Code written as follows:
if ((c++ = d++) != 0) {
is just bad coding. First, the the inner assignment within a comparison. Then the postfix operators within it. Both contribute to a block of code that is difficult to read, easy opportunities for bugs, difficult to maintain etc... Better written as follows:
c = d;
c++;
d++;
if (c == d) {
But you already knew that. :)

java operator precedence with assignment

I would be grateful if someone could please explain why the following is occuring. Thanks a lot.
boolean b = true;
// Compiles OK.
// The LHS "assignment operand" requires no ()parentheses.
if (b=true || b==true);
// Reverse the ||'s operands, and now the code doesn't compile.
if (b==true || b=true);
// Add () around the RHS "assignment operand", and the code now compiles OK.
if (b==true || (b=true));
Edit -
BTW, the compilation error for code line #2 is: "unexpected type", and occurs where the short-circuit OR operator is located:
if (b==true || b=true);
// ^ "unexpected type" compilation error occurs here.
Edit 2 -
Please note that the code fragments found in this question are examples of "highly artificial Java coding", and consequently would not be seen in professionally written code.
Edit 3 -
I'm new to this incredibly useful website, and I've just learnt how to make and upload screenshots of Java's compilation messages. The following image replicates the information that I provided in my first "Edit" above. It shows the compilation error for example code line #2.
The assignment operator = has lower precedence than the logical or operator || so that you can use the logical operator in an assignment without extra pairs of parentheses. That is, you would want to be able to write
a = b || c;
instead of being forced to write a = (b || c).
Unfortunately, if we work with operator precedence only, this rule also applies to the left hand side of the expression. a || b = c must be parsed as
(a || b) = c;
even if what you intended was a || (b = c).
Assignments have the lowest precedence in Java. Thus, your first two expressions are equivalent to:
if ( b = (true || b==true) );
if ( (b==true || b) = true );
The second one doesn't compile because the expression (b==true || b) is not an lValue (something that can be assigned to).
If you add parentheses, you do the assignment before the OR, and everything works.
Using operator precedence (http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html) we have this (I added parentheses to indicate precedence):
if (b=(true || (b==true))), b will be assigned to expression and returns boolean, so it fits for condition;
if (((b==true) || b)=true), left side doesn't fit for assignment operator (as it is expression rather than variable);
if (((b==true) || (b=true))), boolean comprates to boolean with OR, right boolean is boolean because b is variable and = returns the assigned value.

Categories

Resources