Since in C/C++ floating-point literals without a suffix default to type **double** , then assigning such a literal to a **float** performs an implicit conversion from **double** to **float** .

```
float n = 3.14;
if(n == 3.14f)
puts("Igual");
```

This does not print the message instead if we add the suffix **f** to 3.14 in the declaration of **n** to prevent the conversion if printed. The question is, is there a loss of precision when the conversion is carried out?

## Ask

Yes, there is a loss of precision.

## Narrowing .

_The floating point data types are:

`float`

: Single precision. They are usually a 32-bit wide type following IEEE-754 32-bit.`double`

- Double precision. They are usually a 64-bit wide type following IEEE-754 64-bit.`long double`

- Extended accuracy. They are usually an 80-bit type on 32-bit and 64-bit architectures. Does not necessarily follow IEEE-754 .Every time you go from a type of higher precision to one of less, a narrowing occurs; data can be lost every time a narrowing occurs, when does this happen?

## Type conversion.

According to the C standard in the

`§6.3.1.5`

Real Floating Point Typessection (translation and emphasis mine):In your case, assigning the value

`3.14`

to a`float`

corresponds to a narrowing, but since the value is exactly`3.14`

representable by the value will not change.`float`

## What is failing?

If the value has not changed, why does your code fail?:

Because I lied, the value

`3.14`

is NOT representable by`float`

exactly. There are floating point numbers that are not exactly representable in binary, this is due to the properties of each base^{1}.The value 3.14 in binary is not exactly representable and with double precision its value is approximately 3.140000000000000

12434497875802but by storing it in a`float`

you have lost some precision, how much exactly? It will depend on your system...So you will be comparing a number like the truncation of the value

`double`

3.14000000000000012434497875802 against a number like`3.14f`

that in many cases will not be the same number. For example the literal 3.14 in float is approximately 3.1400001049041748046875so your comparison would be, more or less:That obviously does not comply with equality.

## It's terrible! What I can do?

As eferion comments , you should avoid comparing floating point numbers by equality, due to rounding errors you should compare them by

almost equality, a function like this could help you:`FLT_EPSILON`

The and values`DBL_EPSILON`

are the difference between 1 and the next value representable by`float`

and`double`

respectively; in other words, they are approximately the smallest value representable by each of the types, so if the difference between`izquierda`

and`derecha`

is less than or equal to this value, both values arealmost equal.^{1}For example, 1/3 in base 10 is a pure periodic number of value 0.3333333... while in base 12 it is exactly 0.4. In decimal the value 1/10 is exactly 0.1 but in binary it is a mixed periodic number of value 0.00011001100110011...Floating point numbers should

never everbe compared using the comparison operator.The reason is that these numbers have a certain precision, the rest of the digits being practically random.

The correct way is to perform the comparison assuming a certain margin of error:

You can play with the precision to adapt it to your needs. The example is simply illustrative.

All the best

Here is a very illustrative example of what happens. And it really is worth explaining.

You have two uninitialized memory areas like so:

Area A:

Area B:

Then you put a

`float`

in A:And one

`double`

in B:So by comparing A to B, you get the comparison of:

With

Being these different. I hope it was educational for you.