Keep in mind that casting from a long to a float is still considered a widening conversion. Seems strange as a long is 64 bits and a float is only 32, doesn't it?
But it's true.
Here's the reasoning...
A widening conversion is a conversion in which you can convert a value of one type to that of another type safely (without losing data). Converting an int to a byte is obviously not safe as you might lose a lot of data. So, why then, is a conversion from a long to a float "safe?"
Well, the answer is in the ranges. What's the maximum value of a long?
2^63 - 1
What's the maximum value of a float?
(2-2^-23)*2^127
Which one is greater? Obviously, the maximum value of a float is higher. Therefore, any value that falls within the range of a long also falls within the range of a float. That makes a conversion from a long to a float "safe."
How is that possible if a long is 64 bits and a float is 32 bits. Well, the answer to that question lies in the way we interpret those bits. Bits are bits - the computer sees them as 1's and 0's and nothing more. We, however, interpret them in some way. When we look at a long, we see a 63 bit representation of a value and a sign bit. When we look at a float, we see much more - there's a sign bit and there's a number in there, but there's also an exponent. Floats and doubles are the
Java version of scientific notation, so to speak.
Certainly, you can write out 1,000,000,000, but you can also write 1x10^9 and save yourself a few characters. It's the same way with longs and floats.
However, there's one caveat here. When you boil it all down, 64 bits is still more than 32 bits and there are more combinations possible with 64 bits than there are in 32 bits. Therefore, even though a given long value falls within the "range" of a float, there is always a chance that the value is question can't be represented
exactly by a float. What you end up with is an awfully close approximation.
So, I've probably gone into greater detail than you needed, but keep in mind that the order of conversions from int to double (from narrowest to widest) goes something like this:
int -> long -> float -> double
I hope that helps,
Corey