Win a copy of The Way of the Web Tester: A Beginner's Guide to Automating Tests this week in the Testing forum!

# SCJP 1.5 implicit cast of long to double

Harry Henriques
Ranch Hand
Posts: 206
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
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
Posts: 21744
85
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
Posts: 20709
68
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: 15568
46
Moving to the SCJP forum.

Roger Pack
Greenhorn
Posts: 4

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.