using += and ternary operator in java clarification - java

I was running through some practice questions for an upcoming exam and came across a question that me nor my class mates can seem to understand. It is as follows:
where all variables are int or int array.
score += (rounds[i]) ? i + START : 0
How does the ternary operator work in java with += ?
This is my understanding:
so it is score += round[i] == i+start or == 0.
Is this a correct understanding?
Kind regards,
James

As with any combination of operators, it's a question of operator precedence and (where the operators have the same precedence) associativity. In Java, the simple assignment and all the operator/assignment operators share the lowest precedence tier. The ternary operator is the sole occupant of the next higher precedence tier. Therefore, your expression is equivalent to
score += ((rounds[i]) ? (i + START) : 0)
That is, the ternary expression is evaluiated, and its result is the right-hand operand of the +=.
As others have observed, that's not valid in Java if the type of rounds[i] is int, though that would be ok in C. But the expression could be sensible in Java if rounds[i] were an array of boolean, or it could be rewritten like this ...
score += ((rounds[i] != 0) ? (i + START) : 0)
... on the assumption that a C-style boolean interpretation of integer rounds[i] is what is wanted.

score += (some condition which is true or false) ? value to add if true : value to add if false;

We can try it.
int START = 3;
int score = 0;
boolean[] rounds = { true, false };
for (int i = 0; i < rounds.length; i++) {
score += (rounds[i]) ? i + START : 0;
System.out.format("i is %d, score is %d%n", i, score);
}
Output:
i is 0, score is 3
i is 1, score is 3
So the first time through the loop i is 0 and rounds[i] is true. In this case Java adds i and START to get 3 and adds this to score. Second time i is 1 and rounds[i] is false, so instead just 0 is added.
The statement you ask about adds a value to score. The value added is i + START if rounds[i] can be evaluated to true and 0 if it’s false. If i and START are both numeric, a number will be added. If score is numeric, adding 0 usually makes no difference, so you may think of the statement as adding a value only if rounds[i] is true.
so it is score += round[i] == i+start or == 0.
No, there is no implicit == comparison in the statement (as others have said, it requires that rounds[i] is a Boolean value, true or false).

The ternary operator ?: is used as follows:
a = bolean_expression ? this if true : else this if false.
int start = 5;
// In this case, start was added to itself to obtain 10.
start += true ? start : 0;
System.out.println(start); // prints 10
// with out the compound assignment operator (+=) the
// expression should be enclosed in ()
start = start + (true ? start : 0);
System.out.println(start); // prints 20
In the above cases, if the boolean was false, the start always have the value 5 since 0 would be added each time.

Related

For what value of i does while (i == i + 1) {} loop forever?

I ran cross this puzzler from an advanced programming course at a UK university exam.
Consider the following loop, in which i is, so far, undeclared:
while (i == i + 1) {}
Find the definition of i, that precedes this loop, such that the while loop
continues for ever.
The next question, which asked the same question for this code snippet:
while (i != i) {}
was obvious to me. Of course in this other situation it is NaN but I am really stuck on the prior one. Does this have to do with overflow? What would cause such a loop to loop for ever in Java?
First of all, since the while (i == i + 1) {} loop doesn't change the value of i, making this loop infinite is equivalent to choosing a value of i that satisfies i == i + 1.
There are many such values:
Let's start with the "exotic" ones:
double i = Double.POSITIVE_INFINITY;
or
double i = Double.NEGATIVE_INFINITY;
The reason for these values satisfying i == i + 1 is stated in JLS 15.18.2. Additive Operators (+ and -) for Numeric Types:
The sum of an infinity and a finite value is equal to the infinite operand.
This is not surprising, since adding a finite value to an infinite value should result in an infinite value.
That said, most of the values of i that satisfy i == i + 1 are simply large double (or float) values:
For example:
double i = Double.MAX_VALUE;
or
double i = 1000000000000000000.0;
or
float i = 1000000000000000000.0f;
The double and float types have limited precision, so if you take a large enough double or float value, adding 1 to it will result in the same value.
These puzzles are described in detail in the "Java Puzzlers: Traps, Pitfalls, and Corner Cases" book by Joshua Bloch and Neal Gafter.
double i = Double.POSITIVE_INFINITY;
while (i == i + 1) {}
or:
double i = 1.0e40;
while (i == i + 1) {}
both will result in an infinite loop, because adding 1 to a floating-point value that is sufficiently large will not change the value, because it doesn't "bridge the gap" to its successor1.
A note about the second puzzle (for future readers):
double i = Double.NaN;
while (i != i) {}
also results in an infinite loop, because NaN is not equal to any floating-point value, including itself 2.
1 - Java Puzzlers: Traps, Pitfalls, and Corner Cases (chapter 4 - Loopy Puzzlers).
2 - JLS §15.21.1
double i = Double.POSITIVE_INFINITY;
Just an idea: what about booleans?
bool i = TRUE;
Isn't this a case where i + 1 == i?

Java confused by this syntax

boolean riddle = !( 1 < 8 || (5 > 2 && 3 < 5));
boolean is a true or false.
! = not
|| = or
&& = and
but I still dont understand this syntax... can someone explain me what this syntax excactly does?
Just dissect it:
There are some comparisons such as
5 > 2 ... true
3 < 5 ... true
Those two are pulled together using &&; so true && true --> true
1 < 8 ... true
That one is or'ed to the rest; so we get true or true --> true
Finally, not (true) --> false
Long story short: if you don't understand the whole picture, break it down into the parts you understand; and then pull those together again.
Edit: and of course, the order I am using in my explanation isn't what happens in reality. There, 1 < 8 is evaluated first; and as that is true; and "true or X" is always true, the other comparisons are not even computed.
The not ! operator negates what it is in front of. In this case !() it will produce the opposite of the what is inside of the parenthesis.
the || or operator checks to see if one condition or the other is true. At least one must be true for the condition to return true.
Finally the && checks both sides of the conditional statement to see if they are both true, and both of them must be true to proceed.
boolean riddle = !( 1 < 8 || (5 > 2 && 3 < 5));
Let's parse it the way Java does :
boolean : Here comes a boolean, i.e. true or false.
riddle : The variable riddle is declared to be a boolean.
= : The boolean variable riddle is initialized with the expression on the right.
!(...) : It returns a boolean, the negation (=opposite) of the boolean inside of the parentheses.
Inside the parentheses is a bool1 || bool2 expression, where || is a "lazy OR" operator. If bool1 is true, there's no need to evaluate bool2.
bool1 is 1 < 8, which is true.
bool2 isn't evaluated
bool1 ||bool2 is true
!(...) is false
riddle is initialized with false
At no point in time are 5 > 2 or 3 < 5 evaluated. Eclipse warns that those 2 expressions are "dead code" and could be removed.
The whole expression could be :
boolean riddle = !( 1 < 8 || (5 > 2 && doSomethingVeryDangerous()));
the result would be the same and no method call would happen at all.
The problem that you have is that you initialize at the same time as you are checking if it's true or false. You cannot compare boolean with integer. If you want to do it then you need to solve it in another way by converting from one datatype to another, or involve another variable in your solution. The way you need to solve your syntax problem is by dividing it like this:
How you did it...
boolean riddle = !( 1 < 8 || (5 > 2 && 3 < 5));
How to potentially solve it...
boolean riddle;
"...some code to decide if riddle will be true or
false and assign it to the variable riddle..."
if (riddle == true){
"...do some code here...";
}
if (riddle == false){
"...do some code here...";
}
Or you can solve the problem by not using boolean as datatype and instead only use integers like this...
int riddle;
"...some code to decide what value riddle will
have and assign it to the variable riddle..."
if ( riddle < 8 && riddle > 1){
"...do some code here...";
}

What is the difference += and +?

I was asked a question what the difference is between having counter += 5 and counter + 5 in the java programming language. I said they essentially do the same thing but I did not know how to explain why. I felt one was considered a shorthand representation of the same problem but now thinking about it more, I feel I am not correct. Can anyone give me a simple explanation the difference between them?
counter += 5 modifies counter. counter += 5 can be used as a statement (e.g. line of code) on its own, because it does something (increments counter by 5).
counter + 5 does not modify anything. counter + 5 can only be used as an expression within a statement, because it doesn't do anything on its own.
Here is some code that demonstrates the difference:
int counter = 1;
System.out.println(counter + 5); // 6
System.out.println(counter); // 1
// counter + 5; // not a valid statement
counter += 5; // counter is now 6
System.out.println(counter); // 6
System.out.println(counter += 5); // 11
System.out.println(counter); // 11
counter += 5 is assigning the value of whatever counter was plus 5 to the counter variable while counter+5 is return the result of 5 plus counter but the counter variable stays the same.
+= operator
For example you have a a variable counter that equals 3. When you do counter += 5, you are actually assigning a new value to the variable counter. so if counter was 5 and you do counter+=3, counter will now equal 8.
+ operator without the equal
In this case if your counter equals 3. when you do counter+3 it will return 8 for that instance but your counter will still be 3.
Code to demonstrate the differences:
int counter = 3;
counter += 5;
int y = 0;
/*this will return 8, since the result of 5 and counter was newly assigned to
counter*/
System.out.println(counter);
//resetting counter value.
counter =3;
y = counter+5;
//here counter still remains at 3, because there wasn't anything assigned to it
System.out.println(counter);
//will return 8, because you assigned the result of counter and 5 to y.
System.out.println(y);
Only the JLS holds the true answer!
(Assuming count is a numeric type. If it's a String, for example, then everything everyone told you above is wrong at the time I wrote this.)
+= operator
JLS 15.26.2 Compound Assignment Operators:
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
following,
[...] the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator.
[...] the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.
(emphasis mine). In the above above notation, E1 and E2 will perform the operation indicated by += (meaning E1 + E2). The result is stored in E1.
+ operator
JLS 15.18.2. Additive Operators (+ and -) for Numeric Types:
The binary + operator performs addition when applied to two operands of numeric type, producing the sum of the operands.
Note that there is no assignment here.
counter += 5 is the one that is shorthand, but it's shorthand for counter = counter + 5. counter + 5 is just an expression, what you get is a value that is 5 greater than the value of counter, but this value is just left behind and nothing is done with it. In order for something else to happen, an additional operator needs to be present, such as the =, or assignment operator. This operator takes an expression on the right hand side and an identifier on the left, evaluating the expression and assigning the result to the identifier. Without assignment, values don't change, and even when you use methods that seem to change values without assignment (String.append() for example) there is an assignment hidden in the code of the function. As an added fact, counter += 5 can be reduced (if you really want to call it reducing it) to counter++ used 5 times.

Why can't I use ?: operators in the 3rd argument of for loops in Java?

Why is the following code giving me an error?
int n = 30000; // Some number
for (int i = 0;
0 <= n ? (i < n) : (i > n);
0 <= n ? (i++) : (i--)) { // ## Error "not a statement" ##
f(i,n);
}
It's because the for loop has been defined that way in the Java Language Specification.
14.14.1 The basic for statement
BasicForStatement:
for ( ForInit ; Expression ; ForUpdate ) Statement
ForStatementNoShortIf:
for ( ForInit ; Expression ; ForUpdate ) StatementNoShortIf
ForInit:
StatementExpressionList
LocalVariableDeclaration
ForUpdate:
StatementExpressionList
StatementExpressionList:
StatementExpression
StatementExpressionList , StatementExpression
So it needs to be a StatementExpression or multiple StatementExpressions, and StatementExpression is defined as:
14.8 Expression statements
StatementExpression:
Assignment
PreIncrementExpression
PreDecrementExpression
PostIncrementExpression
PostDecrementExpression
MethodInvocation
ClassInstanceCreationExpression
0 <= n ? (i++) : (i--) is none of those, so it is not accepted. i += ((0 <= n) ? 1 : -1) is an assignment, so it works.
First of all, I would recommend against writing the code this way. The purpose of the code is "count up from zero to n if n is positive, count down from 0 to n if n is negative", but I would be inclined to instead write:
for (int i = 0; i < abs(n); i += 1)
{
int argument = n < 0 ? -i : i;
f(argument, n);
}
But that does not answer your question, which is:
Why can't I use ?: operators in the 3rd argument of for loops in Java?
A for loop has the structure for ( initialization ; condition ; action ).
The purpose of an expression is to compute a value.
The purpose of a statement is to take an action.
There are some expressions which by design both compute a value and take an action. i++, i += j, new foo(), method() and so on.
It is bad style to have any other expression that both computes a value and takes an action. Such expressions are difficult to reason about.
Therefore the action of the for loop is restricted to be only those expressions which by design both compute a value and take an action.
Basically, by forbidding this code the compiler is telling you that you've made a bad stylistic choice. b?i++:i-- is a legal expression but it is really bad style because it makes what is supposed to be computing a value into producing a side effect and ignoring the value.
replace
0 <= n ? (i++) : (i--)
with
i += ((0 <= n) ? 1 : -1)
that should work
Your code is giving you an error mostly because you're trying to solve your problem with invalid algorithm. The fact that JLS doesn't allow ternary as a condition in for loop doesn't help either - but the main problem is that you miss the valid solution of the task at hand.
Let's start with a common statement, prematureOptimization == sqrt(sum(evil)) - first you should consider what you want to do, not how to do it or why the code doesn't work.
the loop should just execute n times, using i as a counter
i step should be 1 if n is >= 0, otherwise -1
(side note: if n is invariant (and it is here) using e.g. abs(n) or n < 0 in the condition is a bad practice; although most compiler will try to factor the invariant out of the loop, you should usually simply use a temporary var to store the result and use the result in the comparison instead)
So, the code at hand should be:
void doSomething( int n ) {
if ( n >= 0 )
for( int i = 0; i < n; i++ )
f( i, n );
else
for( int i = 0; i > n; i-- )
f( i, n );
}
Factoring out invariants and separating distinct code branches are basic techniques used to increase algorithms efficiency (not a premature optimization, mind me); there's no faster nor more clean way to do this. Some may argue this is a case of loop unwinding - it very well would be, if not for the fact that those two loops shouldn't be wound together in the first place...
Another thing: third op in for loop was always an ordinary statement; let's try to guess why doesn't the following code compile?
0 <= n ? (i++) : (i--); // error: not a statement
... maybe because following code won't compile either?
0 <= n ? i : i; // error: not a statement
... and that's for the very same reason code below won't work in Java either?
i; // error: not a statement
Your answer is: ternary is not a statement - ternary just returns the value, and value is not a statement (at least in Java); i++ and i-- are allowed in ternary just because they return a value, but they also produce side effects here.

Is it possible to find out which number is bigger without using an if statement?

I'm doing some small program for a beginners programming course and in my program I have 2 variables which hold numbers. Anyway I need to find out which number is bigger and print the appropriate message according to it, for example I have:
int x = 5;
int y = 10;
I need to print:
"it is true that y is bigger than x";
Now the thing is that I know I can use a simple if statement but I'm not allowed to use it, now it makes me wonder, is it even possible? If so, how can I do that? How can I check which number is bigger WITHOUT doing something like:
if (x > y)
answer = true;
...
Thanks in advance.
Well you can do:
boolean answer = x > y;
The expression x > y is just an expression of type boolean. While boolean expressions are often used for conditions in if statements, loops etc, they don't have to be - simple assignment works fine too.
It sounds like you want the reverse though:
boolean answer = y > x;
Then you can use the value of answer to build the string to display...
Use the ternary operator:
System.out.println(x > y ? "It is true that x is greater than y" : "");
ternary operator "?:"
String output = (x > y)? "x is greater than y":"y is greater than x";
The ternary conditional operator that others mentioned will work. Assuming you are looking for creative ways to do this rather than practical ones, here's another method:
int x = 5;
int y = 10;
while(y > x){
System.out.println("It is true that y is bigger than x.");
return;
}
System.out.println("It is false that y is bigger than x.");
The while is just acting as a fancy if, because the return means the otherwise infinite loop will only execute at most once.
Here's another example that instead relies upon short-circuit boolean evaluation:
public static void main(String...args){
int x = 5;
int y = 10;
boolean answer = (y > x);
boolean testTrue = answer && printTrue();
boolean testFalse = testTrue || printFalse();
}
private static boolean printFalse() {
System.out.println("It is false that y is bigger than x.");
return true;
}
private static boolean printTrue() {
System.out.println("It is true that y is bigger than x.");
return true;
}
Of course you shouldn't do this in real production code, but it can be fun to think of unorthodox ways to code something and it can be helpful for exploring the language.
Your question is tagged as Java but you do not specify Java in your question. In Java there are multiple ways to get the same result that involve testing the boolean expression x > y somehow, such as the ternary operator. I would consider these equivalent to an explicit if statement.
Other possibilities:
Compute the square root of x - y. This will raise an exception if y is bigger. Catch the exception in the caller and report that y is the larger quantity. If there is no exception, report that x is the larger.
In LISP, Ruby or another language that supports the symbol type, form a list ((symbol x, x), (symbol y, y)) and sort the list. Then report the second symbol as the variable with the larger value.
If using assembly, BASIC, PL/1, etc. you can use an arithmetic expression to choose the target of a GOTO statement. Depending on whether x or y is larger, execution will resume at a different part of the code. Or use the list-sorting trick in the previous bullet to select the GOTO label.
In general, the expression ((x - y) / abs(x - y) + 1) / 2 will produce 1 if x is larger and 0 if y is larger. This result could be used to choose data, a function, etc. out of a list of two alternatives, producing conditional behavior without an if statement.
You could use recursion (but I would not recommend it)
public int compare ( int a , int b )
{
switch ( a )
{
case Integer.MIN_VALUE :
switch ( b )
{
case Integer.MIN_VALUE :
return 0 ;
default :
return -1 ;
}
default :
switch ( b )
{
case INteger.Min_VALUE :
return 1 ;
default :
return compare ( a-1 , b-1 ) ;
}
}
}
(a+b)/2 + Abs(a-b)/2 is the bigger number.
I know in some languages you can use short-circuit evaluation to construct the answer.
The expression (A && B) always evaluates to B if A is true. If A is false then B is never evaluated.
Similarly (A || B) evaluates to B if A is false. If A is true B is never evaluated.
Though I'm not 100% sure of Java, the expression you want is:
String output = ((x > y) && "it is true that X is greater than Y")
|| (((x < y) && "it is true that X is less than Y")
|| "it is true that X is equal to Y");

Categories