I have seen this question asked before. However, I am not satisfied with the answers that are given. Typical responses are that Java sees the number as a double, since that is the default in JAVA, and gives a mismatch error on compiling.
This behavior is apparently totally ignoring my use of a float declaration.
My question is: If I am declaring a variable type as float, why does Java think it is a double? I am specifically declaring:
float x = 3.14;
I have told Java that I want this variable to be a float type by using the float keyword. Why is this required?
float x = 3.14f;
If I want a double type variable, I use the double keyword specifically declaring the variable as a double.
double x = 3.14;
Why does Java not recognize this when declaring a variable and insists the literal needs to be cast from a double to a float by adding the 'f' at the end? Shouldn't Java recognize the use of the keyword float and properly assign the type to the literal?
32-bit float → float x = 3.14 ; ← 64-bit double
The default for a fractional numeric literal in Java is the 64-bit primitive double type, as shown in the Answer by Mark Rotteveel. 3.14 is a double, as is 3.14d and 3.14D.
The primitive float type is smaller, 32-bit.
If Java were to infer that what you said is a double but what you meant is a float, Java would have to reduce the 64-bit value to a 32-bit value, discarding half the data, 32-bits. This could involve data loss for larger numbers. And this would definitely mean a loss of capacity.
So the designers of Java decided to be conservative in this matter. They decided to not be so presumptive as to throw away half your data, nor to reduce your specified capacity by half. They decided to take you at your word — if you said 64-bit double, they give you a double.
If you then go on to say you want to cram that 64-bit number into a 32-bit container, they flag the error, as 64-bits does not fit into 32-bits. Square peg, round hole.
round hole, 32-bit float → float x = 3.14 ; ← 64-bit double, square peg
Java does support the converse, a widening conversion. You can put a 32-bit float into a 64-bit double. And you can put a 32-bit int into a 64-bit long. These operations are safe, as the extra 32-bits can be filled safely with zeros. So Java is willing and able to support these operations.
I suggest you make a habit of being explicit. Do not rely on the default. If you mean a 32-bit float, append the f or F to your literal. If you mean a 64-bit double, append the d or D to your literal.
Doing so not only quiets the compiler, it makes your intentions clear to the humans reading your code.
float pi = 3.14F ;
double pi = 3.14d ;
BigDecimalAnd, by the way, if you care about accuracy rather than performance, you’ll be using BigDecimal rather than float/double. In which case this issue is moot.
BigDecimal pi = new BigDecimal( "3.14" ) ;
The reason is that the Java Language Specification specifies that a floating point literal without the f or F suffix, is a double. From Floating-Point Literals in the Java 15 Language Specification:
A floating-point literal is of type
floatif it is suffixed with an ASCII letterForf; otherwise its type isdoubleand it can optionally be suffixed with an ASCII letterDord.
Java doesn't try to infer the type of the literal based on the type of the variable you're assigning to. A double-literal is simply always a double. In other words, semantically, it behaves the same as if your code did:
double temp = 3.14;
float x = temp;
Which will also fail to compile, because assigning a double to a float can result in loss of information, if the magnitude of the value is too large to fit in a float. This is known as narrowing primitive conversion, and requires an explicit cast to tell the compiler you're aware of the risk and you accept it.
In some cases, it may seem as if Java will perform inference of type from the variable (e.g. when assigning an int or long literal to a double or float variable), but that is because the entire range of int and long can be stored in a float or double (possibly with loss of precision). This is known as widening primitive conversion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With