Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decimal precision of floats

equivalent to log10(2^24) ≈ 7.225 decimal digits

Wikipedia

Precision: 7 digits

MSDN

6

std::numeric_limits<float>::digits10

Why numeric_limits return 6 here? Both Wikipedia and MSDN report that floats have 7 decimal digits of precision.

like image 291
liori Avatar asked Jul 22 '10 14:07

liori


People also ask

How many decimals of precision does a float have?

With a data type, there is a limited number of bits. Those bits cannot accurately represent a value that requires more than that number of bits. The data type float has 24 bits of precision. This is equivalent to only about 7 decimal places.

What is the precision of a decimal?

Precision is the number of digits in a number. Scale is the number of digits to the right of the decimal point in a number. For example, the number 123.45 has a precision of 5 and a scale of 2. In SQL Server, the default maximum precision of numeric and decimal data types is 38.

What precision are Python floats?

In python float precision to 2 floats in python, and python float precision to 3. There are many ways to set the precision of the floating-point values.

Is decimal more accurate than float?

Float stores an approximate value and decimal stores an exact value. In summary, exact values like money should use decimal, and approximate values like scientific measurements should use float. When multiplying a non integer and dividing by that same number, decimals lose precision while floats do not.


2 Answers

If in doubt, read the spec. The C++ standard says that digits10 is:

Number of base 10 digits that can be represented without change.

That's a little vague; fortunately, there's a footnote:

Equivalent to FLT_DIG, DBL_DIG, LDBL_DIG

Those are defined in the C standard; let's look it up there:

number of decimal digits, q, such that any floating-point number with q decimal digits can be rounded into a floating-point number with p radix b digits and back again without change to the q decimal digits.

So std::numeric_limits<float>::digits10 is the number of decimal digits such that any floating-point number with that many digits is unchanged if you convert it to a float and back to decimal.

As you say, floats have about 7 digits of decimal precision, but the error in representation of both fixed-width decimals and floats is not uniformly logarithmic. The relative error in rounding a number of the form 1.xxx.. to a fixed number of decimal places is nearly ten times larger than the relative error of rounding 9.xxx.. to the same number of decimal places. Similarly, depending on where a value falls in a binade, the relative error in rounding it to 24 binary digits can vary by a factor of nearly two.

The upshot of this is that not all seven-digit decimals survive the round trip to float and back, but all six digit decimals do. Hence, std::numeric_limits<float>::digits10 is 6.

There are not that many six and seven digit decimals with exponents in a valid range for the float type; you can pretty easily write a program to exhaustively test all of them if you're still not convinced.

like image 109
Stephen Canon Avatar answered Oct 23 '22 16:10

Stephen Canon


It's really only 23 bits in the mantissa (there's an implied 1, so it's effectively 24 bits, but the 1 obviously does not vary). This gives 6.923689900271567 decimal digits of precision, which is not quite 7.

like image 45
Paul R Avatar answered Oct 23 '22 16:10

Paul R