Why do you need to specify a suffix f
in a float literal?

- 47
- 6

- 18,348
- 50
- 129
- 196
-
4Because otherwise, it won't be a _float_ literal. – SLaks Dec 31 '12 at 14:49
-
1Although it is for C, you might like this quiz on floating-point constant subtleties. I believe each of the five questions would work exactly the same in Java. http://blog.frama-c.com/index.php?post/2011/11/08/Floating-point-quiz – Pascal Cuoq Jan 01 '13 at 12:11
3 Answers
Because otherwise it defaults to double
, which is a more commonly used floating point type than float
.
From the Java Language Specification, section 3.10.2:
A floating-point literal is of type float if it is suffixed with an ASCII letter F or f; otherwise its type is double and it can optionally be suffixed with an ASCII letter D or d (§4.2.3).
(Personally I'd rather there were no default, to make it clear in all cases, but that's a different matter.)

- 1,421,763
- 867
- 9,128
- 9,194
-
1But why then have a deceleration of a type if it defaults to a different type? I understand that double is just a 64 bit float but is there some deeper rationale to doing this? – stackoverflow Dec 31 '12 at 14:54
-
2@stackoverflow: What do you mean? The type of the *literal* is somewhat independent of the type the variable you use. For example, you can use a `float` literal and assign it to a `double` variable. In most cases, the type of an expression is independent of the context in which it's used. (There are situations where types are inferred for generics, but that's a special case.) – Jon Skeet Dec 31 '12 at 15:04
-
1@stackoverflow Java supports [narrowing conversion](http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.2) during assignment of literals to primitives. This is why you can have `float f = 1.0;` even though `1.0` is a double. I guess this is supported because it is unambiguous - unlike using a literal with a method call, for example. – McDowell Dec 31 '12 at 15:59
-
2@McDowell, except `float f = 1.0;` doesn't compile. You need an explicit cast: `float f = (float) 1.0;`. – aioobe Mar 05 '18 at 09:54
Because unsuffixed floating-point literals are doubles, and rounding means that even small literals can take on different values when rounded to float and double. This can be observed in the following example:
float f = (float) 0.67;
if(f == 0.67)
System.out.print("yes");
else
System.out.print("no");
This will output no
, because 0.67 has a different value when rounded to float than it does when rounded to double. On the other hand:
float f = (float) 0.67;
if(f == 0.67f)
System.out.print("yes");
else
System.out.print("no");
… outputs yes
.
EDIT
Second example:
if(0.67 == 0.67f)
System.out.print("Equal");
else
System.out.print("Not Equal");
… outputs Not Equal
.

- 37,270
- 24
- 156
- 208

- 57,103
- 20
- 141
- 208
There are two floating point types that could be represented as e.g. 100.0
. Only one could be the default. Because of its limited precision, float is an extremely specialized type. The normal case is double, so it is the appropriate default.
On modern processors, float and double have similar compute performance. The only case for using float is large arrays in performance critical situations that require limited precision. Using float doubles the number of floating point values that fit in one cache line. Even then, working out whether float gives enough precision for a given calculation is rarely trivial.

- 25,849
- 4
- 38
- 75