471,863 Members | 1,553 Online

# Java Puzzles

13,262 8TB
Parentheses affect the order of evaluation only, except in one situation.
What's that situation?
Jul 22 '08 #1
29 3449
JosAH
11,448 Expert 8TB
When used in a non-arithmetic context as in e.g. if( ... ), while( ... ), for( ... )?

kind regards,

Jos

ps. on second thought: it doesn't change the order of evaluation in "a+(b*c)" either ...
Jul 22 '08 #2
r035198x
13,262 8TB
When used in a non-arithmetic context as in e.g. if( ... ), while( ... ), for( ... )?

kind regards,

Jos

ps. on second thought: it doesn't change the order of evaluation in "a+(b*c)" either ...
When used in a non-arithmetic context sounds correct but is not what I was looking for.

Even if they do not change the order in that expression, their use there is for specifying the order of evaluation.

There is an instance in parenthesized expressions where using them acts to change meaning of a statement (correctness even) without changing the order of evaluation.
Jul 22 '08 #3
JosAH
11,448 Expert 8TB
There is an instance in parenthesized expressions where using them acts to change meaning of a statement (correctness even) without changing the order of evaluation.
Do you mean that *without* those parentheses that statement/expression is
syntactically/semantically incorrect? Or do you mean something silly as:

Expand|Select|Wrap|Line Numbers
1. int a;
2. int b;
3. a= (b= 41)+1; // versus: a= b= 41+1;
4.
kind regards,

Jos
Jul 22 '08 #4
r035198x
13,262 8TB
Do you mean that *without* those parentheses that statement/expression is
syntactically/semantically incorrect? Or do you mean something silly as:

Expand|Select|Wrap|Line Numbers
1. int a;
2. int b;
3. a= (b= 41)+1; // versus: a= b= 41+1;
4.
kind regards,

Jos
Without the parethesis the statement is valid but fails to compile when they are introduced in a manner that does not change the order of evaluation. In your example above the results are different but the parenthesis changed the order of evaluation.
Jul 22 '08 #5
JosAH
11,448 Expert 8TB
Without the parethesis the statement is valid but fails to compile when they are introduced in a manner that does not change the order of evaluation. In your example above the results are different but the parenthesis changed the order of evaluation.
You mean something like this?

Expand|Select|Wrap|Line Numbers
1.
2. b= 1|2; // which is 3
3.
4. if (b == 1|2)            // versus: b == (1|2)
5.    System.out.println("foo");
6.
The precedence of those operators have been wrong ever since K&R1 ...

kind regards,

Jos
Jul 22 '08 #6
r035198x
13,262 8TB
You mean something like this?

Expand|Select|Wrap|Line Numbers
1.
2. b= 1|2; // which is 3
3.
4. if (b == 1|2)            // versus: b == (1|2)
5.    System.out.println("foo");
6.
The precedence of those operators have been wrong ever since K&R1 ...

kind regards,

Jos
Ah but that's something else. Yep the precedence there is wrong. I hope you did it right in <oops we shouldn't mention it here>.

As in the previous example, introducing the brackets changes the order of evaluation. The circumstance I'm looking for is when introducing the brackets does not change the order or evaluation but changes the syntactic correctness of the statement.
Jul 22 '08 #7
1,216 Expert 1GB
Not what you're looking for, but "()" changes the value:

Expand|Select|Wrap|Line Numbers
1. public class Example {
2.     public static void main(String[] args) {
3.         new Example().run();
4.     }
5.
6.     public void run() {
7.         System.out.println(name); //1
8.         System.out.println(name()); //2
9.     }
10.
11.     int name = 1;
12.
13.     int name() {return 2;}
14. }
Jul 22 '08 #8
JosAH
11,448 Expert 8TB
Not what you're looking for, but "()" changes the value:
Cute, that one slipped my mind ;-)

kind regards,

Jos

ps. r035198x, is that what you were looking for?
Jul 22 '08 #9
r035198x
13,262 8TB
Not what you're looking for, but "()" changes the value:

Expand|Select|Wrap|Line Numbers
1. public class Example {
2.     public static void main(String[] args) {
3.         new Example().run();
4.     }
5.
6.     public void run() {
7.         System.out.println(name); //1
8.         System.out.println(name()); //2
9.     }
10.
11.     int name = 1;
12.
13.     int name() {return 2;}
14. }
Clever but not what I was going for.
I have to go for the day. Here goes ....
Expand|Select|Wrap|Line Numbers
1. long aLong = -9223372036854775808L;
vs
Expand|Select|Wrap|Line Numbers
1. long aLong = -(9223372036854775808L);
Jul 22 '08 #10
JosAH
11,448 Expert 8TB
Cute, that one also slipped my mind; in fact we have several occasions where
those parentheses can cause unexpected hickups ...

kind regards,

Jos
Jul 22 '08 #11
r035198x
13,262 8TB
.. in fact we have several occasions where
those parentheses can cause unexpected hickups ...

kind regards,

Jos
Perhaps not as many in parenthesized expressions with the order of evalauation not changed by their introduction.

Do I have to give today's reading as well?
Jul 23 '08 #12
JosAH
11,448 Expert 8TB
Do I have to give today's reading as well?
Yes! Then I keep my big mouth shut for a couple of hours so others can answer.

kind regards,

Jos
Jul 23 '08 #13
r035198x
13,262 8TB
Is the isEven method in the class below a valid check for even numbers and why of course?

Expand|Select|Wrap|Line Numbers
1. class Test {
2.
3.     int eval(int x, int ... vals) {
4.         return (x % 2 == 0) ? 2 : 2;
5.     }
6.
7.     int eval(double x) {
8.         return (x % 2 == 0) ? 2 : 1;
9.     }
10.
11.     int eval(Integer x) {
12.         return (x % 2 == 0) ? 2 : 2;
13.     }
14.
15.     static boolean sameFalse() {
16.         return true?false:true == true?false:true;
17.     }
18.     //Is this a valid test for even numbers?
19.     static boolean isEven(int x) {
20.         boolean even = (new Test().eval(x) & 1) == 0;
21.         return even != sameFalse();
22.     }
23.     public static void main(String[] args) {
24.         System.out.println( isEven(7));
25.
26.     }
27. }
Jul 23 '08 #14
Brosert
57
At a guess...

there are 2 things to consider here:
the eval's and sameFalse....

Eval first & third are identical, and return 2 irrespective of the input
Eval second returns 2 if even, 1 if not....
I think (though not certain - Java is not my lang of choice) that Java 5 (and beyond?) will pick either the third one (box the int as an Integer), or the first one (but I'm pretty sure not the second)...
So I think
Expand|Select|Wrap|Line Numbers
1. eval(x) &1
2.
will always return 0 (ie even = true) irrespective of x....

Looking at sameFalse, specifically the line:
Expand|Select|Wrap|Line Numbers
1. return true?false:true == true?false:true;
2.
I'm pretty sure the operator precedence means that it is evaluated as the equivalent of
Expand|Select|Wrap|Line Numbers
1. return true?false:((true==true)?false:true)
2.
this will always return false.....
thus we return
Expand|Select|Wrap|Line Numbers
1. true != false;
2.
Which is true.
This means (if my analysis was correct) even will ALWAYS return true (irrespective of input)

However, if I was wrong in the assessment of eval, and the second one is the one that is used, I think it would work....
Jul 24 '08 #15
r035198x
13,262 8TB
Hi Brosert, thanks for playing close.

The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.
...
The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.
...
The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing and unboxing.

The purpose of the division into phases is to ensure compatibility with older versions of the Java programming language which didn't have autoboxing and varargs.
Jul 24 '08 #16
JosAH
11,448 Expert 8TB
The purpose of the division into phases is to ensure compatibility with older versions of the Java programming language which didn't have autoboxing and varargs.
I had to look that one up (no cheating involved here ;-) as well. That chapter 15
has always been the lousiest chapter from the book; I guess the authors managed
to postpone or redirect all the complicated stuff to that chapter and finally they

Now there's only one part left to solve ...

kind regards,

Jos
Jul 24 '08 #17
blazedaces
284 100+
Well, I was a bit curious at first. I assumed something must be up. This line in particular got me thinking:
Expand|Select|Wrap|Line Numbers
1. boolean even = (new Test().eval(x) & 1) == 0;
A number & 1 would produce 0 if even and 1 if odd. But only the second method (as Brosert explained above) produces two distinct results.

So if for some unknown reason eval(double x) would be chosen over the two for int and Integer, this would indeed be a valid check for even numbers.

Well, I was too curious to wait, so I ran the program myself. If the result was always "even" for both even and odd numbers, then the method chosen is the first or third and otherwise it is the second. Lo and behold:

If main is:
Expand|Select|Wrap|Line Numbers
1. public static void main(String[] args) {
2.         for(int i = 0; i < 20; i++) {
3.             System.out.print(i + " is ");
4.             if(isEven(i)) {
5.                 System.out.println("Even");
6.             } else {
7.                 System.out.println("Odd");
8.             }
9.         }
10.     }
11.
Then the output is:
Expand|Select|Wrap|Line Numbers
1. 0 is Even
2. 1 is Odd
3. 2 is Even
4. 3 is Odd
5. 4 is Even
6. 5 is Odd
7. 6 is Even
8. 7 is Odd
9. 8 is Even
10. 9 is Odd
11. 10 is Even
12. 11 is Odd
13. 12 is Even
14. 13 is Odd
15. 14 is Even
16. 15 is Odd
17. 16 is Even
18. 17 is Odd
19. 18 is Even
20. 19 is Odd
21.
Can anyone explain to me why double is chosen. I apologize, but the quoted sections you have provided don't make that much sense to me. Perhaps I am all too unfamiliar with the terminology.

Thanks much,
-blazed <-- loves to solve puzzles :)
Jul 29 '08 #18
r035198x
13,262 8TB
...
Can anyone explain to me why double is chosen. I apologize, but the quoted sections you have provided don't make that much sense to me. Perhaps I am all too unfamiliar with the terminology.

Thanks much,
-blazed <-- loves to solve puzzles :)
When faced with multiple applicable methods (I'll leave it to you to find out what "applicable method" means) there is need to select the most specific method. This is done in three phases ...
First we look for a method that matches the parameters without performing any boxing/unboxing and while considering any varargs as arrays. That leaves only the double method available.
Jul 29 '08 #19
blazedaces
284 100+
When faced with multiple applicable methods (I'll leave it to you to find out what "applicable method" means) there is need to select the most specific method. This is done in three phases ...
First we look for a method that matches the parameters without performing any boxing/unboxing and while considering any varargs as arrays. That leaves only the double method available.
This makes a lot more sense to me now, thank you. When it analyzes an int as a double does it cast int as a double first or are the bits left as is... I'm just curious. I could probably run a test myself to find out...

Now, one last question. I had never before seen "int ... vals". I assume this works similarly to matlab's varargs since you mention this right above (maybe matlab took it from java...). That's very interesting. A good option to have.

-blazed
Jul 29 '08 #20
r035198x
13,262 8TB
This makes a lot more sense to me now, thank you. When it analyzes an int as a double does it cast int as a double first or are the bits left as is... I'm just curious. I could probably run a test myself to find out...

Now, one last question. I had never before seen "int ... vals". I assume this works similarly to matlab's varargs since you mention this right above (maybe matlab took it from java...). That's very interesting. A good option to have.

-blazed
Those indeed are varags (refered to as variable airity in the JLS). They are here with us only since JDK 1.5.
Jul 29 '08 #21
blazedaces
284 100+
Those indeed are varags (refered to as variable airity in the JLS). They are here with us only since JDK 1.5.
Lol. Every time I think finally, something java CAN'T do... they pull something like this on me ... *shakes fist at java*

-blazed
Jul 29 '08 #22
When used in a non-arithmetic context as in e.g. if( ... ), while( ... ), for( ... )?

kind regards,

Jos

ps. on second thought: it doesn't change the order of evaluation in "a+(b*c)" either ...

when condition has true
Aug 11 '08 #23
Well, I was a bit curious at first. I assumed something must be up. This line in particular got me thinking:
Expand|Select|Wrap|Line Numbers
1. boolean even = (new Test().eval(x) & 1) == 0;
A number & 1 would produce 0 if even and 1 if odd. But only the second method (as Brosert explained above) produces two distinct results.

So if for some unknown reason eval(double x) would be chosen over the two for int and Integer, this would indeed be a valid check for even numbers.

Well, I was too curious to wait, so I ran the program myself. If the result was always "even" for both even and odd numbers, then the method chosen is the first or third and otherwise it is the second. Lo and behold:

If main is:
Expand|Select|Wrap|Line Numbers
1. public static void main(String[] args) {
2.         for(int i = 0; i < 20; i++) {
3.             System.out.print(i + " is ");
4.             if(isEven(i)) {
5.                 System.out.println("Even");
6.             } else {
7.                 System.out.println("Odd");
8.             }
9.         }
10.     }
11.
Then the output is:
Expand|Select|Wrap|Line Numbers
1. 0 is Even
2. 1 is Odd
3. 2 is Even
4. 3 is Odd
5. 4 is Even
6. 5 is Odd
7. 6 is Even
8. 7 is Odd
9. 8 is Even
10. 9 is Odd
11. 10 is Even
12. 11 is Odd
13. 12 is Even
14. 13 is Odd
15. 14 is Even
16. 15 is Odd
17. 16 is Even
18. 17 is Odd
19. 18 is Even
20. 19 is Odd
21.
Can anyone explain to me why double is chosen. I apologize, but the quoted sections you have provided don't make that much sense to me. Perhaps I am all too unfamiliar with the terminology.

Thanks much,
-blazed <-- loves to solve puzzles :)

Respected Sir
Actually i want to know do u run this code, If so then what kind of error is listed for u.

Coz it say "isEven" means....!!!
Aug 11 '08 #24
JosAH
11,448 Expert 8TB
Respected Sir
Actually i want to know do u run this code, If so then what kind of error is listed for u.

Coz it say "isEven" means....!!!
That code may be twisted obfuscated code but it doesn't cause any errors,
neither compilation errors nor runtime errors.

I'm sorry I don't understand your last line. btw. that code needs Java 1.5 or later.

kind regards,

Jos
Aug 11 '08 #25
blazedaces
284 100+
Respected Sir
Actually i want to know do u run this code, If so then what kind of error is listed for u.

Coz it say "isEven" means....!!!
As JosAH said there were no errors. I copied the exact code provided and I showed what my main was and what output the computer spit out.

The output sort of implies there were no errors...

-blazed
Aug 11 '08 #26
jkmyoung
2,057 Expert 2GB
Expand|Select|Wrap|Line Numbers
1. long aLong = -9223372036854775808L;
vs
Expand|Select|Wrap|Line Numbers
1. long aLong = -(9223372036854775808L);
? This does change the order of evaluation.
In the first, a long is created with that value.
In the second, a long is created with the positive value. It is then made negative. So, the second option requires at least 2 additional assembly instructions.

I protest this solution.

Would argue the following is better:
Expand|Select|Wrap|Line Numbers
1. long aLong = 1 + 2 + 3;
2. long bLong = (1 + 2) + 3;
3.
The order of evaluation is not changed in this case.
Nov 4 '08 #27
r035198x
13,262 8TB
In your example the result is not changed by the introduction of the brackets (i.e introducing the brackets does not change anything).
Try the solution that I gave and you will see that one of them doesn't even compile! (i.e the brackets change the correctness).
Nov 5 '08 #28
jkmyoung
2,057 Expert 2GB
Parentheses affect the order of evaluation only, except in one situation.
What's that situation?
I think there are 2 possible situations:
1. Parentheses affect result.
2. Parentheses do not affect order of evaluation or result.

After rereading the post #3, I'm guessing you're going for 1, as 2 seems to have already been stated in Jos first post (#2). Still I protest the solution given in post #10, as it changes order of operation but not result, the exact opposite of what is asked for.

My favourite answer is still post #8.
Nov 12 '08 #29
r035198x
13,262 8TB
...Still I protest the solution given in post #10, as it changes order of operation but not result, the exact opposite of what is asked for.
..
My argument is that in the solution I gave, the brackets render the statement
Expand|Select|Wrap|Line Numbers
1. long aLong = -(9223372036854775808L);
incorrect. It does not compile at all so there is no change in the order of operation because there is no operation done at all.
The fascinating thing is that
Expand|Select|Wrap|Line Numbers
1. long aLong = -9223372036854775808L;
compiles successfully.
Nov 13 '08 #30