Binary floating-point is designed to approximate real-number arithmetic. It is not designed to record information about decimal digits. If you want to work with decimal arithmetic, you should use a format other than the float
or double
types of your compiler.
For float
, your C implementation most likely uses the IEEE-754 basic 32-bit binary format, also called binary32. The number 2.34 cannot be represented in this format. In float no =2.34;
, the source text 2.34
is a double
constant, and the decimal “2.34” is converted to the nearest value representable in a double, which is 2.339999999999999857891452847979962825775146484375, if your C implementation uses the IEEE-754 binary64 format and uses round-to-nearest-ties-to-even, both of which are common. This double
value is then used to initialize no
, which is a float
, so it is converted to the nearest value representable in the float
format, which is 2.3399999141693115234375.
If your code correctly counted the number of decimal digits after the decimal point required to represent this number, it would print 22. One reason it does not is because the operation no*10
produces more rounding errors. In binary, ten is 10102, and multiplying by it increases the number of bits needed to represent result without rounding error. Since float
has a fixed number of bits, it is not possible to use more bits. So the real-number result is rounded to fit. Each time your program executes no=no*10
, it loses some information about the number.
Consider that both float no = 2.34;
and float no = 2.3399999141693115234375;
yield exactly the same result in no
. Therefore, no difference between them can be detected from that value. So no software could tell whether the numeral with two digits after the decimal point or the numeral with 22 digits after the decimal point had been used to initialize no
.
Therefore, no software can tell you how many digits that original numeral had, if all it has to use is the value in no
.
It is possible to figure out the shortest decimal numeral that would produce a particular float
value. Java and JavaScript provide this in their default formatting for floating-point numbers. Then one could count the digits in that numeral. However, this is useful only for situations where a floating-point result is known to be equal to the result of converting some numeral with a limited number of decimal digits to binary floating-point. If the floating-point result comes from calculations, we cannot expect it to be near a short decimal numeral. For example, if no
came from other calculations and were just a little higher or lower, the float
value would be one of the neighboring values, 2.340000152587890625 or 2.339999675750732421875, near decimal numerals “2.3400002” and “2.3399997”. Generally, when working with binary floating-point arithmetic, we should not expect to get simple decimal results.