# The type of a floating point literal with exponent

By default, all floating point literals, with or without an exponent part, have type `double`

. You can add the `f`

suffix to make the type `float`

or `L`

to make the type `long double`

.

In the case of `float f = 123456e-3;`

, you're initializing a `float`

with a `double`

constant, so there is the possibility of loss of precision, however this particular constant only has 6 decimal digits of precision so it should be OK.

What is the type of a floating-point literal?

**Floating constants**

C defines these as *floating constants*, not *literals*. Default type is `double`

.

An `f`

or `F`

suffix makes it a `float`

.

An `l`

or `L`

suffix makes it a `long double`

.

**[edit] FLT_EVAL_METHOD**

C has `FLT_EVAL_METHOD`

which allows *constants* to be *interpreted* as a wider type.

Example `FLT_EVAL_METHOD == 2`

evaluate all operations and constants to the range and precision of the

`long double`

type.

In this case, I'd expect `v1`

and `v2`

to have the same value when `FLT_EVAL_METHOD == 2`

, but different values when `FLT_EVAL_METHOD == 0`

.

```
long double v1 = 0.1;
long double v2 = 0.1L;
```

When used as a float initializer in float f = 123456e-3; does it need to have a f suffix?

For best conversion of the text to `float`

, yes use an `f`

.

`float f = 123456e-3`

incurs double rounding. 2 rounding occurs: text->`double`

and `double`

to `float`

.

With select values, `g`

may get a different value with `float g = x.xxx`

vs `g = x.xxxf;`

. See following.

**double rounding example**

Notice `f2`

and `f4`

have the same constant except the the `f`

suffix. Compiler warns with `f4`

:

warning: conversion from 'double' to 'float' changes value from '9.9999997019767761e-1' to '1.0e+0f' [-Wfloat-conversion]

```
#include <stdlib.h>
int main(void) {
// float has 24 bit significand, double has 53
float f1 = 0x0.FFFFFFp0f; // code with 24 bit significand, exact as a float
printf("%-20a %.17e\n", f1, f1);
float f2 = 0x0.FFFFFF7FFFFFFCp0f; // code with 54 bit significand, rounds down to nearest float
printf("%-20a %.17e\n", f2, f2);
float f3 = 0x0.FFFFFF80000000p0f; // code with 25 bit significand, rounds up to nearest float
printf("%-20a %.17e\n", f3, f3);
puts("");
double d1 = 0x0.FFFFFF7FFFFFF8p0; // code constant with 53 bit significand, exact as a double
printf("%-20a %.17e\n", d1, d1);
double d2 = 0x0.FFFFFF7FFFFFFCp0; // code constant with 54 bit significand, rounds up to nearest double
printf("%-20a %.17e\n", d2, d2);
float f4 = 0x0.FFFFFF7FFFFFFCp0; // code constant with 54 bit significand, rounds up to nearest double
// then rounds up again when double converted to float
printf("%-20a %.17e\n", f4, f4);
return 0;
}
```

Output

```
0x1.fffffep-1 9.99999940395355225e-01
0x1.fffffep-1 9.99999940395355225e-01 f2
0x1p+0 1.00000000000000000e+00
0x1.fffffefffffffp-1 9.99999970197677501e-01
0x1.ffffffp-1 9.99999970197677612e-01
0x1p+0 1.00000000000000000e+00 f4 Double Rounding!
```

For best conversion of the text to `long double`

, definitely use an `L`

else the constant is only a `double`

with less precision.

```
long double ld1 = 0x1.00000000000001p1;
printf("%.20Le\n", ld1, ld1);
long double ld2 = 0x1.00000000000001p1L; // "Same" constant as above with an 'L'
printf("%.20Le\n", ld2, ld2);
```

Output

```
2.00000000000000000000e+00
2.00000000000000002776e+00
```

For floating point literal, if no suffix is defined, it will be automatically considered as `double`

.

You can follow this chart for suffix:

```
(no suffix) - double
f/F - float
l/L - long double
```

So, for float, it needs to have `f`

or `F`

suffix.