Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > Java > Java and JDK > Java Basics
Password Reminder
Register
| FAQ | Members List | Search | Today's Posts | Mark Forums Read
Java Basics General beginning Java language questions that don't fit in one of the more specific forums. Please specify what version.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the Java Basics section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old July 11th, 2008, 11:52 PM
Registered User
 
Join Date: Jul 2008
Location: , , USA.
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default possible loss of precision

I am going through Ivor Horton's Java 2 JDK 5 Edition. I have version 6 on my machine. I'm doing Chapter 2 Exercise 1 where we initialize and declare a variable "byte number = 1;" We are to multiply it by 2 eight 8 times to go beyond the capacity of byte. I chose to use the statement "number = number * 2;" but got this error message when I did.

"Ch2Ex1.java:5: possible loss of precision
found : int
required: byte
   number = number * 2;"
                   ^

I looked at the sample given and changed my statement to
"number *= 2;" and it compiled and it gave the expected error on the last output.

Is "number = number * 2;" and "number *= 2;" two different ways of saying the same thing? The whole purpose of the exercise is to loose precision. Why does the first way get an error message and not the second?


Reply With Quote
  #2 (permalink)  
Old July 12th, 2008, 01:45 AM
Friend of Wrox
 
Join Date: Jun 2008
Location: Snohomish, WA, USA
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
Default

This is one of the oddities of Java.

FIrst of all "possible loss of precision" is *NOT* an error; it is just a warning.

You will note that the warning says "found: int, required: byte".

What it is saying is that the expression on the RIGHT side of the equals sign is an integer, but the variable on the left side is only a byte. So, when you assign the integer to the byte, indeed you could "lose precision". And you will, if the integer value is larger than 255.

WHY is the expression on the right side an integer??? When the variable number is just a byte?? Simply because the constant 2 is, by Java definition, an integer. And any time you do mixed-type arithmetic, the values are "promoted" to the largest precision type. [Actually, with Java it's a tad more complicated than that, but for this example that statement is true enough.]

Now, most of us were always taught that
     number *= 2;
is IDENTICAL to
     number = number * 2;

And it's true that the numeric result will be the same. But the big difference is that Java *KNOWS* (for some weirdo reason...but you need a real Java afficianado and guru to tell you the gory details) that you are asking for a "byte only" operation. And so no warning message. And you only finally get an error when you really do exceed the capacity of the byte.

Again, there are some esoteric reasons why the behavior here changed between JDK 5 and JDK 6. In some magic way, the version 6 behavior is "more correct."

If you care a lot, I think I could probably find the chapter and verse that explains the change; but honest, for 99.4% of all practical purposes, it doesn't matter.

And if you really really care a lot, then buy this book:
http://www.amazon.com/Java-TM-Puzzle...5844842&sr=8-1
The book explains not only this point but dozens of other tricks and edge cases. And convinces you that language designers must all be just a little crazy. (Having designed a couple in my own time, I can attest that the latter is definitely true.)
Reply With Quote
  #3 (permalink)  
Old July 12th, 2008, 08:54 PM
Registered User
 
Join Date: Jul 2008
Location: , , USA.
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks for your response. Just a note "First of all "possible
loss of precision" is *NOT* an error; it is just a warning."
that this warning does not let you compile. With in us is a
standard of perfection that we fail to measure up to, it's no surprise that our computer systems fail in the same way. In the future if I see this warning I'll know to change the code. I appreciate having someone online to talk this over with.

Reply With Quote
  #4 (permalink)  
Old July 13th, 2008, 10:48 PM
Friend of Wrox
 
Join Date: Jun 2008
Location: Snohomish, WA, USA
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
Default

Huh...another change with JDK 6, I guess. "Possible" was always a warning, as I remember it.

Then answer, of course, is to do
    byteVariable = (byte) (2 * byteVariable);
casting the integer result to byte.

But what a pain. Now you make me almost want to go look that oddity up in that "Puzzler" book (I remember it being in there) to see the rationale.
Reply With Quote
  #5 (permalink)  
Old July 20th, 2008, 10:51 PM
Registered User
 
Join Date: Jul 2008
Location: , , USA.
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I have all ready declared my variable as byte, and number = (byte)(number * 2) compiles OK. I was thinking "number" is already a byte and 2 might be the problem so I tried number = number * (byte)2; but got the same error message

Ch2Ex1.java:7: possible loss of precision
found : int
required: byte
   number = number * (byte) 2;

Reply With Quote
  #6 (permalink)  
Old July 21st, 2008, 04:36 PM
Friend of Wrox
 
Join Date: Jun 2008
Location: Snohomish, WA, USA
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
Default

Java never does arithmetic in anything smaller than integer precision.

http://java.sun.com/docs/books/jls/t...ues.html#4.2.2

So casting the 2 to a byte does nothing to change that.

You would need to cast the *result* of the operation to byte.

Thus:

     number = (byte)(number * 2);

Note that section 5.2 of those same docs certainly says you need that cast there to prevent a compile time error. (You can then still get a runtime error, of course, but that's a different matter.)

Ahhh...and here's where the docs clearly spell out why
     byte number = 1;
     number *= 2;
is different than
     byte number = 1;
     number = number * 2;

http://java.sun.com/docs/books/jls/t...s.html#15.26.2

The very first sentence says it all:
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.

So
     byte number = 1;
     number *= 2;
truly *IS* equivalent to
     byte number = 1;
     number = (byte) (number * 2);
!!!!!!!!

See, not so esoteric, after all!

It is that implicit cast *OF THE RESULT* that the *= operator produces that is missing in the other case.


Reply With Quote
  #7 (permalink)  
Old July 23rd, 2008, 02:42 PM
Registered User
 
Join Date: Jul 2008
Location: , , USA.
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks for the documentation links. Doing this kind of research is something I would like to learn. I looked up the word esoteric and it is a mysterious specialized knowledge amongst an inner circle of people. From what I understand, there is a cutting edge group of people developing the Java software. There is two types of knowledge discernment and wisdom. Discernment is knowing what a situation is and wisdom is knowing what to do about it. For example you discerned my error message and recommended casting the right side of the equation to (byte). This recommendation is wisdom, but this wisdom is based on our knowledge of the situation. Our knowledge is a thin spider web that stretches over reality. The mystery is the imperfection or incompleteness of that knowledge. Admitting the mystery is mental humbleness and I think is a good thing.

Reply With Quote
  #8 (permalink)  
Old September 19th, 2008, 09:41 PM
yulin11
Guest
 
Posts: n/a
Default

yeah. I think that it is because you implicitly convert the int type to the byte typle. You know that the int and the byte typle have different length in java. So it will lose precision.

everyone can go far!www.codeuu.com
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Stored procedure decimal precision filipczako SQL Language 11 December 7th, 2005 04:21 PM
Float precision nulogix C++ Programming 1 November 10th, 2005 09:53 PM
How to control the decimal point precision johnsonlim026 ASP.NET 1.0 and 1.1 Basics 0 August 7th, 2005 11:58 PM
I'm at a loss with IIS 5.1... wrofox Classic ASP Basics 0 September 19th, 2004 02:19 PM
Number precision problem adriant42 Excel VBA 2 June 28th, 2004 01:00 PM



All times are GMT -4. The time now is 05:07 AM.


Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.