Saturday, December 19, 2009

Why double-to-float Conversion Always Needs an Explicit Cast

A few days ago, I finally found the answer to the question that I posed in my previous post, thanks to Steve Luke's reply at JavaRanch. I created a post in the Beginning Java forum there, which led to a refresher for me on the subject of floating-point types and their ranges. An int literal may be implicitly narrowed on assignment to a byte variable if the literal value is within the range of a byte (The range of a floating-point type (double or float) is a little more complex. Apart from the possibility of overflow or underflow to positive or negative infinity, there is also the possibility of underflow to zero. This could occur if the absolute value of a number is too small for the type. So, while a double may be within the minimum and maximum float values, it may be too close to zero to fit into a float. Here is an illustration of underflow to zero from The Java Language Specification (Third Edition) (sec. 5.1.3, pg. 84). The output of:

System.out.println("(float)1e-50==" + (float)1e-50);

is:

(float)1e-50==0.0

So, the compiler refuses to implicitly convert any double value to a float. I guess that is simpler for the lazy compiler than to calculate whether the literal double value can be accurately represented as a float. Reading Section 4.2.3 Floating-Point Types, Formats, and Values of the Java Language Specification, I can see why this might not be a trivial deduction.

No comments: