• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Rob Spoor
  • Devaka Cooray
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
  • Tim Holloway
Bartenders:
  • Jj Roberts
  • Al Hobbs
  • Piet Souris

OCP Java SE 11 Programmer I Study Guide (Sybex) Possible Errata

 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Page 82 table 3.1, && must be in a separate/higher row than || since && has precedence over ||
 
Bartender
Posts: 3731
39
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi !

Welcome to CodeRanch!

Can you share the source about the precedence you used?

For me these operations identical, executed from left to right:



prints:



if && had higher precedense, then first c2 would be printed.

 
Saloon Keeper
Posts: 1606
52
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Mikalai:

This is a little subtle.

I think the reasoning you gave might not cover all cases of precedence, because the operands get evaluated left to right in every case, with the lone exception of the short-circuit operators which do not necessarily evaluate all their operands, yet even there, the ones that will be evaluated are evaluated left to right.

Let me explain.

The problem doesn't concern the non-short-circuit logical operators, but I have confirmed they *are* in scope for the exam as long as they aren't being used for bitwise arithmetic on integral types.

The precedence of those is:
&
^
|

Okay, if the question was instead this one:


Then it would be correct to say that & is higher precedence than |, because, it is.

Yet, the operands for the logical operators would still be evaluated left-to-right by calling the methods which are invoked:


Here we see that c1(), c2(), c3() get invoked in order from left to right, despite the fact that & is higher priority than |, yes?
However, the results of the operations happen as if we had said:
( c1() ) | ( c2() & c3() )
due to precedence rules.

Similarly, if we change the problem to this:

and re-run, we will see:

jshell> LogicalTest.main(args);
c1
c2
c3
7


Note that the operands to the operators are still evaluated left-to-right, regardless of precedence.
However, once again, the operations only are performed according to the rules of precedence, i.e. the multiplication operation occurs before the addition, analogously to the non-short-circuit logical operations shown above.

So I would avoid saying this sentence:

if && had higher precedense, then first c2 would be printed.



Some people make fun of him, many others revere him as a Guru, but the unique Delivery/Presentation of Durga Sir from DurgaSoft in his lectures causes me to remember things forever that I might forget.

Doing one of these problems with his class, which I watched in the video, he responded to one of his students getting something like this wrong with "Oy!!  Oy!!  This is just order of operations!!  There is no such thing as precedence of Operands, all evaluations is simply left to right!!"

Everyone watching in person laughed, as did I, but it certainly helped me to stop forgetting this subtle difference between the order of performing the operations with the order of evaluating the operands.

In some expressions there are no side-effects from evaluation of the operands, so it does not matter, the tree is falling in the forest with nobody there to hear it.
If the evaluation of the operands has any side effects that can be seen from the outside world, we will see that the operands are always evaluated left to right, but that the operations are performed according to the rules of precedence and associativity.

 
Andrius Orlonas
Greenhorn
Posts: 8
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Mikalai Zaikin, thanks for welcoming . In c1() + c2() * c3() the "*" also has precedence over the "+" but that does not prevent from executing c1() first. I mean operator precedence does not change the order of evaluation, it acts more like a grouping of expressions.
 
Andrius Orlonas
Greenhorn
Posts: 8
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Example on page 84 (bottom):

int lion = 3;
int tiger = ++lion * 5 / lion--;

if the postfix "--" had a precedence of evaluation (sounds weird) over * and / the answer would be a mess. Now it is like

((++lion) * 5) / (lion--)

For the conclusive evidence on the matter please see the table in
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
 
Enthuware Software Support
Posts: 4580
45
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You may want to check out this article on Precedence, Associativity, and Evaluation order in Java as well. It covers everything you need for the exam.
 
Andrius Orlonas
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am using the Enthuware book alongside with the Sybex, and so far it seems the author of the Enthuware book has the way better understanding what he is talking/writing about, explaining concepts and under the hoods, also reaching pages ~200 on each book found no mistakes or ambiguities in the Enthuware book while the Sybex one seems to be published in a very hurry...
 
Jesse Silverman
Saloon Keeper
Posts: 1606
52
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a lot of respect for the Sybex book and authors, but on this topic, that assessment may be correct.

I actually provided a lot of feedback on the Enthuware materials, so it is even possible I might be part of the reason for the smooth sailing with that material, Paul would know.

Regardless, as to Paul's provided link:

This is about as close to perfect as one could get in such a short piece.

I only have two (remaining) comments on that version.

I am kinda old, but the acronym I used in school was PEMDAS, which I recall because the terms we used to remember it was supposed to be "Please Excuse My Dear Aunt Sally".
As smart-ass kids, we kept saying "Please Excuse My Dumb Aunt Sally" because, well, we were kids and that seemed funnier to us.
It made it easier to remember it all these years.
As in both mathematics and Java programming, * and / have the same precedence, this is a distinction without a difference, as the saying goes, so no more about it here.

As seen in the various presentations on "Things Every Programmer Should Know About Floating Point Arithmetic) commutativity and associativity and distribution rules that apply in normal maths may not work there due to undeflow and overflow conditions.

So when everything is some float type, you can not presume that:
(a + b)  * c == a * c + b * c

and various other things where adding a very large number to a very small number may have part or all of the result of some sub-stage of the calculation essentially disappear.

Probably beyond the scope of this section and this part of the exam.  My attempt to cook up a quick example of this also failed, but again, probably out of scope here.

What is in scope is possibly the best names for the operators, or an explanation of these:
bitwise AND &
bitwise exclusive OR ^
bitwise inclusive OR |
logical AND &&
logical OR ||


The first three are bitwise operations when the operands are of any integral type, but logical operations when the operands are both of type boolean.
If you try to mix them on an integral type and a boolean, that will simply fail to compile -- this is not C.

bitwise operations on integers are outside of the scope of the 819 these days, for better or for worse.

But when used on boolean values they are still in scope.

Here, I would prefer to call them "non-short-circuit" operators rather than bitwise, because the first and third behave logically similarly to the last two except for lack of short-circuit nature.

They are all logical when applied to booleans, but the last two exhibit short-circuit behavior and the first three do not.

So there are two things that might come up on an exam involving these:
1. The precedence is: & ^ | && ||
2. both operands of the first 3 will always be evaluated, potentially causing a side effect or exception.  When the first operand to && is false, the next operand will NOT be evaluated, when the first operand to || is true, the second operand will not be evaluated.

I just decided to consult the JLS (haven't looked at the Java Tutorials) and they are more careful on the terminology applied to these operators, note:

15.22.2 Boolean Logical Operators &, ^, and |
When both operands of a &, ^, or | operator are of type boolean or Boolean, then
the type of the bitwise operator expression is boolean. In all cases, the operands
are subject to unboxing conversion (§5.1.8) as necessary.
For &, the result value is true if both operand values are true; otherwise, the result
is false.
For ^, the result value is true if the operand values are different; otherwise, the
result is false.
For |, the result value is false if both operand values are false; otherwise, the
result is true.



15.23 Conditional-And Operator &&
The conditional-and operator && is like & (§15.22.2), but evaluates its right-hand
operand only if the value of its left-hand operand is true.
...
15.24 Conditional-Or Operator ||
The conditional-or operator || operator is like | (§15.22.2), but evaluates its righthand
operand only if the value of its left-hand operand is false.



I am very well aware that the terms used on the provided Enthuware page are also in common usage, and the important thing for the exam is to know how they work, I mention it only because after completing this area of study and leaving it behind, seeing that "(integral) bitwise operations are no longer in scope for the 811/819" in a number of places caused me to incorrectly think that & ^ | were out of scope, which they are not.
 
Jesse Silverman
Saloon Keeper
Posts: 1606
52
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, one more try and I got an example where the normal arithmetic/algebraic equivalencies don't hold when doing floating point maths with a mix of large and small numbers.

This is important in Real Life but probably out of scope of the certification exams:

jshell> b * (a + c)
$60 ==> 0.2999159

jshell> b * a + b * c
$61 ==> 0.29991594

jshell> a
a ==> 2.9979247E19

jshell> b
b ==> 1.0E-20

jshell> c
c ==> 1.23456784E16


In general there are two reasons you might use parenthesis that seem logically redundant from the viewpoint of arithmetic and algebra:
a. to avoid making your code hard to read without remembering precedence rules
b. to avoid an overflow or underflow in some partial result compromising accuracy.

This is out-of-scope for the exam, moot if you use BigDecimal and possibly a waste of time mentioning it here, but is in-scope for interviews I am currently engaging in, so, on my mind.
 
Jesse Silverman
Saloon Keeper
Posts: 1606
52
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Trying not to think about it, my mind came up with this obvious example where we use parenthesis to override order of operations because floating point arithmetic is neither associative, commutative or distributive.

Mathematicians know that a * b / c is the same as a * (b / c) and a / c * b

Programmers know that they aren't:
jshell> float a = 2e30F
a ==> 2.0E30

jshell> float b = 3e30F
b ==> 3.0E30

jshell> float c = 4e30F
c ==> 4.0E30

jshell> a * b / c
$4 ==> Infinity

jshell> a * (b / c)
$5 ==> 1.5E30

jshell> a / c * b
$6 ==> 1.5E30


There are plenty of more subtle examples, but this one stands out as obvious.
 
Marshal
Posts: 26909
82
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, engineers have been using floating-point arithmetic basically since it was first available in computers. That would have been in the 1950's. People studying Numerical Analysis (who sometimes called themselves applied mathematicians) quickly discovered problems like that and developed rules to avoid them.
 
Andrius Orlonas
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesse Silverman wrote:Trying not to think about it, my mind came up with this obvious example where we use parenthesis to override order of operations because floating point arithmetic is neither associative, commutative or distributive.

Mathematicians know that a * b / c is the same as a * (b / c) and a / c * b

Programmers know that they aren't:
jshell> float a = 2e30F
a ==> 2.0E30

jshell> float b = 3e30F
b ==> 3.0E30

jshell> float c = 4e30F
c ==> 4.0E30

jshell> a * b / c
$4 ==> Infinity

jshell> a * (b / c)
$5 ==> 1.5E30

jshell> a / c * b
$6 ==> 1.5E30


There are plenty of more subtle examples, but this one stands out as obvious.



I have done some reading about your point in
https://math.stackexchange.com/questions/2333038/what-does-it-mean-that-multiplication-and-division-have-the-same-precedence
Never thought about internals of such "obvious" things and now got puzzled
 
reply
    Bookmark Topic Watch Topic
  • New Topic