• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

SCJP 1.5 implicit cast of long to double

 
Harry Henriques
Ranch Hand
Posts: 206
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I was preparing for the SCJP using K & B SCJP 1.5 Certification textbook. Page 184 in Chapter 3 states the following:

double d = 100L; // Implicit cast
In the preceding statement, a double is initialized with a long value (as denoted by
the L after the numeric value). No cast is needed in this case because a double can
hold every piece of information that a long can store.


I wrote the following snippet to test this assertion using an implicit cast from "long" to "double":



I got the follwing output after successfully compiling the program.

C:\TEMP>java test
9.223372036854776E18

This converts to 9,223,372,036,854,776,000. Obviously, the binary number above doesn't end in three zeros. It appears that the "double" value has lost precision. I don't know if this is an automatic rounding error in the System.out.println() method, or whether the double has indeed lost precision. How can a 64-bit "long" fit into a 64-bit "double" that has a mantissa and exponent?

Thanks.
 
Harry Henriques
Ranch Hand
Posts: 206
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I made an error when I defined a long integer with value 2^63 - 1. I have corrected my mistake. Sorry.




C:\TEMP>java test
9.223372036854776E18 == 9,223,372,036,854,776,000
 
Henry Wong
author
Marshal
Pie
Posts: 21515
84
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No cast is needed in this case because a double can hold every piece of information that a long can store.


This statement isn't really true. Java will allow the implicit cast because the range of a long is smaller than (and within) the range of a double. Some precision will be lost, but precision lost is allowed for an implicit cast.

Henry
 
Rob Spoor
Sheriff
Pie
Posts: 20669
65
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Which is odd because the compiler complains about a "possible loss of precision" when trying to implicitly convert a long to an int, yet this exact same possible loss of permission is allowed when converting from a long to a float or double.

They really should change that error message: "possible range violation" seems better.
 
Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15495
43
Android IntelliJ IDE Java Scala Spring
 
Roger Pack
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

double d = 100L; // Implicit cast
In the preceding statement, a double is initialized with a long value (as denoted by
the L after the numeric value). No cast is needed in this case because a double can
hold every piece of information that a long can store.


I just ran into this too (same book
You can see that it can lead to a loss of precision:

double d = Long.MAX_VALUE; // loses precision
// now since it rounds up in this particular case of losing precision,
d -= 100000;
long d_as_long = (long) d; // force the equals comparison below to compare two long, not doubles
System.out.println("" + (d_as_long == (Long.MAX_VALUE - 100000))); // outputs false

Also this is permitted:
float f = Long.MAX_VALUE; // outputs as 9.223372E18

So I think what the other poster said is right:

Java will allow the implicit cast because the range of a long is smaller than (and within) the range of a double.


So the book seems wrong, but this makes more sense. It allows implicit casting if it will keep the same range, otherwise it doesn't.
 
Don't get me started about those stupid light bulbs.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic