aspose file tools*
The moose likes Beginning Java and the fly likes Problem understanding the ! operator. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Problem understanding the ! operator." Watch "Problem understanding the ! operator." New topic
Author

Problem understanding the ! operator.

Jordan D. Williams
Ranch Hand

Joined: Jan 03, 2012
Posts: 51

Hello there!

I just typed a really long post on here, then I clicked the preview, button, then my mouse "back button" and it all got lost, so I'll make this a lot shorter. [nervous laugh]

Please ignore the cheesy comment in brackets.

Anyway... The point is that I have been learning Java for a little bit of time and I am using Java for Dummies. It has been a great book so far and it does awesome job in explaining OOP and other major and not so major concepts. It has a habit of explaining in detail every line of code in it's examples when it has the potential to throw people off. For this particular piece of code (see below) it did not do that. It didn't really explain how everything fits together. I don't know... Maybe the author assumed I should be able to figure it out, but apparently that is not the case.

Example:


The only part that is unclear to me is "while (!gotGoodInput);". I know that ! by itself is a boolean operator and it flips the value of the variable (true to false; false to true). But in the context of a while statement as a condition for ending the do loop, I don't understand it.

Which value does it flip? Is it the original value of gotGoodInput that is in the declaration/initialization of gotGoodInput or is it the value that is assigned to it in the try statement?

And the follow up question to that is the following. If you assign a "true" value in the initialization of gotGoodInput, and type in "while (gotGoodInput);", why does does the do loop keep going?

Thanks so much for your help!

P.S. I apologize if my question is not clear/specific enough.


John 3:16
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14269
    
  21

Welcome to the Ranch.

The "!" just means "not". So "while (!gotGoodInput)" reads as: while not gotGoodInput, or: while gotGoodInput is not true.

Jordan D. Williams wrote:Which value does it flip? Is it the original value of gotGoodInput that is in the declaration/initialization of gotGoodInput or is it the value that is assigned to it in the try statement?

What is between the ( and ) brackets is an expression that evaluates to a boolean value (true or false). The "!" flips the value of whatever comes after the "!". It looks at the current value of the variable after the "!" when the program reaches that point; so if you assign another value to the variable before the while-statement, then the assigned value is the current value of the variable (line 23). The original value (line 10) has been overwritten by the assignment.

Jordan D. Williams wrote:And the follow up question to that is the following. If you assign a "true" value in the initialization of gotGoodInput, and type in "while (gotGoodInput);", why does does the do loop keep going?

The computer just does exactly what you're telling it to do. The statement "while (gotGoodInput)" means: do the loop again if gotGoodInput is true.

You compile and run the program. You enter something invalid. A NumberFormatException happens in line 20. It jumps to the catch-block (lines 25 - 29) because the exception happened. Note that line 23 is never executed because of this; when the program reaches line 31, gotGoodInput is still set to false because that's what you initialized it with in line 10.

When gotGoodInput is false, line 31 evaluates to: while (!gotGoodInput) -> while (!false) -> while (true) which means the loop is executed again (starting at line 15).

Java Beginners FAQ - JavaRanch SCJP FAQ - The Java Tutorial - Java SE 8 API documentation
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39409
    
  28
What cheesy comments? You haven’t seen cheesy until you see what us mods get up to
Beware of the bang operator “!” It has a higher precedence than * and /, so you very often need () round expressions to get it to compile.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8008
    
  22

Campbell Ritchie wrote:Beware of the bang operator “!” It has a higher precedence than * and /, so you very often need () round expressions to get it to compile.

Just one of the reasons why I (sometimes) prefer to use 'condition == false'.

Your wind-up for the day.

Winston


Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39409
    
  28
You only said that because you know how much I hate == false
Jordan D. Williams
Ranch Hand

Joined: Jan 03, 2012
Posts: 51


The "!" just means "not". So "while (!gotGoodInput)" reads as: while not gotGoodInput, or: while gotGoodInput is not true.
...
What is between the ( and ) brackets is an expression that evaluates to a boolean value (true or false). The "!" flips the value of whatever comes after the "!".


Thank you! That clears it up completely! I was reading the parentheses incorrectly. I was under the impression that they are there because they are required by syntax, but I wasn't aware of their actual function in this expression. That was probably very silly of me to think that there is anything in a computer program that doesn't do anything...

So the way I was reading the statement "while (!gotGoodInput)" was: "while ([take whatever value gotGoodInput has at the time and flip it] is true). Since line 23 would only execute when the user provided good input, the result of the "while (!gotGoodInput)" expression that I saw was "while (gotGoodInput is TURE)" [because it flips the current value of FALSE from line 10. Obviously if gotGoodInput is true, then the loop wouldn't need to continue! .. Needless to say I was VERY confused!

Is it safe to say then that "!" in the said expression changes how the "while" statement is evaluated?

Basically what I mean by that is that in the context of a "do" loop this is the "question" the JVM asks itself:
"while (someVariable)" the "question" is "Do the statements in the "do" loop, while someVariable (or some condition) is true..."

and the converse of that would be:
"while (!someVariable)" the "question" is "Do the statements in the "do" loop, while someVariable (or some condition) is false..."

Is my reasoning correct? I know I probably look like I am going around in circles, saying the same thing (so hopefully I am correct)! I am just trying to get a better handle on this.

Thanks to everyone that replied! All your input has been extremely helpful!

Thank you!

Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8008
    
  22

Jordan D. Williams wrote:...and the converse of that would be:
"while (!someVariable)" the "question" is "Do the statements in the "do" loop, while someVariable (or some condition) is false..."

Is my reasoning correct?

Yes.

Winston
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39409
    
  28
You’re welcome Even though you did allow Gutkowski to write one of my pet hates

If you are going to use == like that, at least do what they would do in C and write while (false == gotGoodInput) ...
At least if you make the mistake of writing = by mistake for == you will get a compiler error rather than a logic error. But I would always writewhile (!gotGoodInput) ... myself.
There is a slightly different way to do it, which sorts out both problems You can use a do loop if yuou prefer. You can also correct my spellling errors!
Jordan D. Williams
Ranch Hand

Joined: Jan 03, 2012
Posts: 51

Campbell Ritchie wrote:
...
You can use a do loop if yuou prefer. You can also correct my spellling errors!


Ah, I see what you mean... The book had a do loop in the example so I just went for it. If I were to go with a while loop only, I would probably call the variable gotBadInput, since the original value is "true".

In the spirit of trying to expand my knowledge, will the code below execute to the same result of your example? Or will the whole "while" loop get skipped, because gotBadInput is never set to "false" before the JVM reaches the "while" loop?

Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14269
    
  21

Jordan D. Williams wrote:In the spirit of trying to expand my knowledge, will the code below execute to the same result of your example? Or will the whole "while" loop get skipped, because gotBadInput is never set to "false" before the JVM reaches the "while" loop?

Yes, that is exactly what happens with the code you wrote below your question.
fred rosenberger
lowercase baba
Bartender

Joined: Oct 02, 2003
Posts: 11416
    
  16

Jordan D. Williams wrote:

Is it safe to say then that "!" in the said expression changes how the "while" statement is evaluated?

Basically what I mean by that is that in the context of a "do" loop this is the "question" the JVM asks itself:
"while (someVariable)" the "question" is "Do the statements in the "do" loop, while someVariable (or some condition) is true..."

and the converse of that would be:
"while (!someVariable)" the "question" is "Do the statements in the "do" loop, while someVariable (or some condition) is false..."

Is my reasoning correct?

I would say no, this is not correct. a while loop always works the same way:

while (whatever is inside here is true)

It doesn't matter if it is a simple boolean or some complicated expression or even a method call. You take what is inside the parens and evaluate it. When you are all done, if it is true, the body of the loop runs. If it is false, the body does not run. This is legal (assuming i have the correct number of parens everywhere:

while (!booleanA && !(booleanB || !booleanC) || (myMethod() > 14))

you evaluate what is inside the parens, which can be very complicated.

Note: most developers would shoot you if you write code this complicated, but it is legal.


There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors
Jordan D. Williams
Ranch Hand

Joined: Jan 03, 2012
Posts: 51

fred rosenberger wrote:
I would say no, this is not correct. a while loop always works the same way...


I think I still need my "ah-haa" moment on this whole thing, but I think I understand what you mean.

I think I didn't express myself correctly. The way the while statement is evaluated doesn't change, as you pointed out, but rather the "!" change the condition upon which the "while" statement evaluates to "true".

"while (someVariable)" -> the "while" statement will evaluate to "true" if and only if "someVariable = true"

and conversely:

"while (!someVariable)" -> the "while" statement will evaluate to "true" if and only if "someVariable = false"

Now is that correct or am I just confusing myself more?

Thank you!
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8008
    
  22

Jordan D. Williams wrote:Now is that correct or am I just confusing myself more?

Looks right to me. I think all Fred was trying to highlight is that all Java language constructs that take a logical expression (while(), if(), do...while()) compare the result of that expression against true in order to determine what to do.

Winston
fred rosenberger
lowercase baba
Bartender

Joined: Oct 02, 2003
Posts: 11416
    
  16

also, the ! can apply to part of the expression, or the whole thing. In my example, you'll see i used three '!'. None change the meaning of the entire statement, but only part of it.

You can think of an expression like this the same way you would evaluate an algebraic expression. You start inside the innermost parentheses, evaluate that, then step out to the next level, etc. Just like an exponent can apply direction to a term: x^2 or to an entire expression: (x + 1)^2, the '!' can apply to a single variable or to a larger expression that ultimately resolves to a boolean.
Jordan D. Williams
Ranch Hand

Joined: Jan 03, 2012
Posts: 51

fred rosenberger wrote:also, the ! can apply to part of the expression, or the whole thing. In my example, you'll see i used three '!'. None change the meaning of the entire statement, but only part of it.

You can think of an expression like this the same way you would evaluate an algebraic expression. You start inside the innermost parentheses, evaluate that, then step out to the next level, etc. Just like an exponent can apply direction to a term: x^2 or to an entire expression: (x + 1)^2, the '!' can apply to a single variable or to a larger expression that ultimately resolves to a boolean.


Oh! I see... That makes all those statements very, very flexible. That's pretty awesome!

Thank you for the clarification. I got it now. I think the best thing for me to do now is just go write some basic programs and mess around with the "!" operator. Nothing can replace experimentation you know .

Thanks for your help!

Winston Gutkowski wrote:Looks right to me. I think all Fred was trying to highlight is that all Java language constructs that take a logical expression (while(), if(), do...while()) compare the result of that expression against true in order to determine what to do


Ahh! I didn't really know that! (When I said I am new, I am really, really new...) It makes perfect sense when I think about it, because I knew that the if () operator works that way.

Thank you very much for your help as well!

*RESOLVED*

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39409
    
  28
It is good when somebody sees the light
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Problem understanding the ! operator.