A direct (literal) expression of a floating point value in source code.
Float literals are used to directly write a decimal value (or any float
or double
) in source code. Floating point literals have
type double
or float
, depending on how
they're specified.
Floating point literals can be expressed through four forms:
1 | decimal-significandfloat-suffix |
2 | decimal-significandexponent |
3 | decimal-significandexponentfloat-suffix |
4 | hex-significandbinary-exponentfloat-suffix |
where...
decimal-significand | is one or more decimal digits (0 , 1 , 2 ,
3 , 4 , 5 , 6 , 7 ,
8 , 9 ), possibly with one decimal point (. )
before, after, or in between any of the digits.In other words, the decimal-significand
is one of:
|
hex-significand | is the string prefix 0x or 0X , followed
by one or more hexadecimal digits (0 , 1 , 2 ,
3 , 4 , 5 , 6 , 7 ,
8 , 9 , a , b , c ,
d , e , f , A , B ,
C , D , E , F ),
possibly with one decimal point (. ) before, after, or in
between any of the digits.In other
words, the hex-significand is one
of:
|
float-suffix | is one of the characters f , F , d ,
or D .
|
exponent | is the character e or E , possibly
followed by a sign symbol (either + or - ),
followed by one or more decimal digits.
|
binary-exponent | is the character p or P , possibly
followed by a sign symbol (either + or - ),
followed by one or more decimal digits. Despite the significand of the number being expressed in
hexadecimal, the binary-exponent
must be specified in decimal. See Note 2
below.
|
such that...
0xfa.1bp+01
== 0xf_a.1_bp+0_1f
.
1 A base-10 floating point literal
using a suffix to indicate whether the literal is of type float
or double
.
2 A base-10 floating point literal
that specifies an exponent. The literal is always of type double
.
3 A base-10 floating point literal that specifies both an exponent and a suffix.
4 A base-16 floating point literal that specifies a binary exponent and, optionally, a suffix.
The value of a floating point literal is calculated by interpreting it
as a number in scientific notation, and then rounding that number to
the closest value in the value set for the literal's
type. The float-suffix, when
included, determines whether the literal is of type double
or float
, and thus determines the corresponding value set. The value set of float
is the
set of all values in the IEEE 754 32-bit single-precision
floating-point format, and the value set for double
is the set of all values in the IEEE 754 64-bit double-precision
format.
If the literal is in base-10 and it includes no exponent, it is simply
interpreted as a base-10, possibly-fractional number. If an exponent is
included, then the interpretation of the literal is the decimal-significand multiplied by 10
to the power of exponent.
Denoting the significand as s
and the exponent as e
,
the interpretation of a base-10 floating point literal is s
× 10e
.
If the literal is in base-16, its interpretation is the hexadecimal-significand multiplied by 2
to the power of binary-exponent.
Denoting the base-16 significand as s
and the base-10
exponent as p
, the interpretation of the literal is s
× 2p
.
Floating point literals' syntax do not provide a direct means of
expressing negative values. A floating point literal that, upon being
rounded to the closest value in its type's value set, rounds to Infinity
,
results in a compile-time error. Additionally, any floating point
literal that rounds to 0
, but is not equal to 0
,
results in a compile time error. This means that literals which are
"too big" (e.g., 1e99f
or 1e999d
) or "too
small" (too close to 0
, e.g. 1e-99f
or 1e-999d
)
to be represented by a float
or double
will
raise compile-time errors. See the below
example for examples.
Even if a floating point literal is too large or small to be expressed
exactly as its corresponding type, so long as rounding the value
of the literal to the nearest value in the value set does not result in
0
or Infinity
, the literal is permitted. For
example, even though the smallest actual float
is
approximately 1.401e-45
, the literal 0.71e-45f
is valid, and can be used in code:
// Use BigDecimal to print exact float value:
System.out.println(new BigDecimal(0.71e-45f));
Note, however, that the value of that float literal is rounded to the
nearest value in the value set for the float
type. The
output of the above code is:
1.40129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125E-45
which is the smallest representable float
.
The exact set of permissible float
literals (those
suffixed with f
or F
) is comprised of the
literals exactly equal to:
0
, or7.00649232162408535461864791644958065640130970938257885878534141944895541342930300743319094181060791015625
but strictly lesser than: 340282356779733661637539395458142568448
.
The exact set of permissible double
literals (those that
have no suffix or have the suffix d
or D
) is
comprised of the literals exactly equal to:
0
, or2.4703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125E-324
but strictly lesser than: 179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497792
.
Any of the literals in the aforementioned sets can be written in a syntactically valid Java program.
This example demonstrates various powers of 2 declared as base-10 and
base-16 literals using exponents. Note that ^
in the
comments is used to denote exponentiation.
// Print 1
System.out.println(1e0); // 1 * 10^0 = 1
System.out.println(0x1p0); // 1 * 2^0 = 1
// Print 2
System.out.println(2e0); // 2 * 10^0 = 2
System.out.println(0x1p1); // 1 * 2^1 = 2
// Print 4
System.out.println(4e0); // 4 * 10^0 = 4
System.out.println(0x1p2); // 1 * 2^2 = 4
// Print 8
System.out.println(8e0); // 8 * 10^0 = 8
System.out.println(0x1p3); // 1 * 2^3 = 8
// Print 16
System.out.println(1.6e1); // 1.6 * 10^1 = 16
System.out.println(0x1p4); // 1 * 2^4 = 16
// Print 32
System.out.println(3.2e1); // 3.2 * 10^1 = 32
System.out.println(0x1p5); // 1 * 2^5 = 32
// Print 64
System.out.println(6.4e1); // 6.4 * 10^1 = 64
System.out.println(0x1p6); // 1 * 2^6 = 64
// Print 128
System.out.println(1.28e2); // 1.28 * 10^2 = 128
System.out.println(0x1p7); // 1 * 2^7 = 128
Output:
1.0
1.0
2.0
2.0
4.0
4.0
8.0
8.0
16.0
16.0
32.0
32.0
64.0
64.0
128.0
128.0
This example demonstrates the effect of the suffix in a literal:
Number d = 1.4; // double value 1.4 gets autoboxed into java.lang.Double object
System.out.println(d.getClass());
Number f = 1.4f; // f suffix to denote float; float value gets autoboxed to java.lang.Float object
System.out.println(f.getClass());
Output:
class java.lang.Double
class java.lang.Float
Another demonstration, involving an overloaded function that takes
either float
or a double
:
class X {
void test(double input) {
System.out.println("Double");
}
void test(float input) {
System.out.println("Float");
}
void runTest() {
test(0.0); // Prints "Double"
test(0.0d); // Prints "Double"
test(0.0f); // Prints "Float"
}
}
Output of calling runTest()
:
Double
Double
Float
This example demonstrates the upper "edge" of the set of permissible float
literals:
// Invalid float; too large:
// float x = 340282356779733661637539395458142568448f; // Float value is out of range.
float y = 340282356779733661637539395458142568447.999f; // Float value is less than the upper bound; this compiles
float z = 340282356779733661637539395458142568447.9999999999999999999999f; // Aribtrarily many digits can be appended.
// System.out.println(x);
System.out.println(y);
System.out.println(z);
// Print exact textual representations of the floats
System.out.println(new BigDecimal(y));
System.out.println(new BigDecimal(z));
Output:
3.4028235E38
3.4028235E38
340282346638528859811704183484516925440
340282346638528859811704183484516925440
Notice how the the literal assigned to x
is greater than
the value output by the final print statements. This is due to the
literals assigned to y
and z
being rounded
to the closest valid float
, which is what is output in
the two final print statements.
0x123p+01_f
is syntactically
invalid. This is because f
in this case is an indicator
as to the type of the literal, rather than a digit that determines the
literal's value.
e
and E
are also hexadecimal digits, when defining a floating point number in
hexadecimal, p
and P
are used to indicate
the exponent part, rather than e
or E
(as
are used for the exponent part of decimal floating point literals).