sign in | join about | help | sitemap
Connecting Tech Pros Worldwide
r035198x's Avatar

Java Puzzles


Question posted by: r035198x (Administrator) on July 22nd, 2008 12:39 PM
Parentheses affect the order of evaluation only, except in one situation.
What's that situation?
29 Answers Posted
JosAH's Avatar
JosAH July 22nd, 2008 01:49 PM
Moderator - 8,361 Posts
#2: Re: Java Puzzles

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 ...
r035198x's Avatar
r035198x July 22nd, 2008 02:21 PM
Administrator - 11,298 Posts
#3: Re: Java Puzzles

Quote:
Originally Posted by JosAH
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.
JosAH's Avatar
JosAH July 22nd, 2008 02:28 PM
Moderator - 8,361 Posts
#4: Re: Java Puzzles

Quote:
Originally Posted by r035198x
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;


kind regards,

Jos
r035198x's Avatar
r035198x July 22nd, 2008 02:36 PM
Administrator - 11,298 Posts
#5: Re: Java Puzzles

Quote:
Originally Posted by JosAH
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;


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.
JosAH's Avatar
JosAH July 22nd, 2008 03:04 PM
Moderator - 8,361 Posts
#6: Re: Java Puzzles

Quote:
Originally Posted by r035198x
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");


The precedence of those operators have been wrong ever since K&R1 ...

kind regards,

Jos
r035198x's Avatar
r035198x July 22nd, 2008 03:12 PM
Administrator - 11,298 Posts
#7: Re: Java Puzzles

Quote:
Originally Posted by JosAH
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");


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.
BigDaddyLH's Avatar
BigDaddyLH July 22nd, 2008 03:21 PM
Moderator - 1,214 Posts
#8: Re: Java Puzzles

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. }
JosAH's Avatar
JosAH July 22nd, 2008 03:32 PM
Moderator - 8,361 Posts
#9: Re: Java Puzzles

Quote:
Originally Posted by BigDaddyLH
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?
r035198x's Avatar
r035198x July 22nd, 2008 03:34 PM
Administrator - 11,298 Posts
#10: Re: Java Puzzles

Quote:
Originally Posted by BigDaddyLH
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);
JosAH's Avatar
JosAH July 22nd, 2008 04:02 PM
Moderator - 8,361 Posts
#11: Re: Java Puzzles

Cute, that one also slipped my mind; in fact we have several occasions where
those parentheses can cause unexpected hickups ...

kind regards,

Jos
r035198x's Avatar
r035198x July 23rd, 2008 07:29 AM
Administrator - 11,298 Posts
#12: Re: Java Puzzles

Quote:
Originally Posted by JosAH
.. 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?
JosAH's Avatar
JosAH July 23rd, 2008 07:42 AM
Moderator - 8,361 Posts
#13: Re: Java Puzzles

Quote:
Originally Posted by r035198x
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
r035198x's Avatar
r035198x July 23rd, 2008 09:16 AM
Administrator - 11,298 Posts
#14: Re: Java Puzzles

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. }
Brosert's Avatar
Brosert July 24th, 2008 01:59 AM
Member - 53 Posts
#15: Re: Java Puzzles

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 

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;

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)

this will always return false.....
thus we return
Expand|Select|Wrap|Line Numbers
  1. true != false;

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....
r035198x's Avatar
r035198x July 24th, 2008 08:31 AM
Administrator - 11,298 Posts
#16: Re: Java Puzzles

Hi Brosert, thanks for playing close.

Quote:
Originally Posted by JLS

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.
JosAH's Avatar
JosAH July 24th, 2008 05:07 PM
Moderator - 8,361 Posts
#17: Re: Java Puzzles

Quote:
Originally Posted by r035198x
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
had to bite the bullet.

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

kind regards,

Jos
blazedaces's Avatar
blazedaces July 29th, 2008 01:09 AM
Needs Regular Fix - 275 Posts
#18: Re: Java Puzzles

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.     }


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


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 :)
r035198x's Avatar
r035198x July 29th, 2008 07:41 AM
Administrator - 11,298 Posts
#19: Re: Java Puzzles

Quote:
Originally Posted by blazedaces
...
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.
blazedaces's Avatar
blazedaces July 29th, 2008 02:25 PM
Needs Regular Fix - 275 Posts
#20: Re: Java Puzzles

Quote:
Originally Posted by r035198x
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
r035198x's Avatar
r035198x July 29th, 2008 02:32 PM
Administrator - 11,298 Posts
#21: Re: Java Puzzles

Quote:
Originally Posted by blazedaces
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.
blazedaces's Avatar
blazedaces July 29th, 2008 03:12 PM
Needs Regular Fix - 275 Posts
#22: Re: Java Puzzles

Quote:
Originally Posted by r035198x
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
29rakesh29's Avatar
29rakesh29 August 11th, 2008 11:01 AM
Newbie - 1 Posts
#23: Re: Java Puzzles

Quote:
Originally Posted by JosAH
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
gnomeom's Avatar
gnomeom August 11th, 2008 04:53 PM
Newbie - 2 Posts
#24: Re: Java Puzzles

Quote:
Originally Posted by blazedaces
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.     }


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


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.

Please i want to know
Coz it say "isEven" means....!!!
JosAH's Avatar
JosAH August 11th, 2008 06:14 PM
Moderator - 8,361 Posts
#25: Re: Java Puzzles

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

Please i want to know
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
blazedaces's Avatar
blazedaces August 11th, 2008 06:40 PM
Needs Regular Fix - 275 Posts
#26: Re: Java Puzzles

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

Please i want to know
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
jkmyoung's Avatar
jkmyoung November 4th, 2008 09:30 PM
Moderator - 869 Posts
#27: Re: Java Puzzles

Quote:
Originally Posted by r035198x
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;

The order of evaluation is not changed in this case.
r035198x's Avatar
r035198x November 5th, 2008 07:01 AM
Administrator - 11,298 Posts
#28: Re: Java Puzzles

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).
jkmyoung's Avatar
jkmyoung November 12th, 2008 10:54 PM
Moderator - 869 Posts
#29: Re: Java Puzzles

Quote:
Originally Posted by
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.
r035198x's Avatar
r035198x November 13th, 2008 06:19 AM
Administrator - 11,298 Posts
#30: Re: Java Puzzles

Quote:
Originally Posted by jkmyoung
...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.
Reply
Not the answer you were looking for? Post your question . . .
197,039 members ready to help you find a solution.
Join Bytes.com

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 197,039 network members.
Post your question now . . .
It's fast and it's free

Popular Articles

Top Java Contributors