• 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: 21190
80
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: 20546
56
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: 15354
39
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.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic