3

I see this in Wikipedia log 224 = 7.22.

I have no idea why we should calculate 2^24 and why we should take log10......I really really need your help.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 1
    Better to change your picture link to a link to the wikipedia article.. – chux - Reinstate Monica Apr 22 '18 at 03:38
  • 1
    They say "7 to 6", because of how the values are distributed, they can represent some values with a precision of 7 digits, but others only with a precision of 6. You calculate 2^24 because that is the number values that can be represented in the mantissa. You take log10 of that because you want to have digits in base 10, while the mantissa is 24 bits (i.e. base 2) in size, i.e. it can represent 2^24 unique values. In other words, you are calculating how many base-10 digits fit in 24 base-2 digits (or bits). – Rudy Velthuis Apr 23 '18 at 16:52

3 Answers3

7

why floating-points number's significant numbers is 7 or 6 (?)

Consider some thoughts employing the Pigeonhole principle:

  1. binary32 float can encode about 232 different numbers exactly. The numbers one can write in text like 42.0, 1.0, 3.1415623... are infinite, even if we restrict ourselves to a range like -1038 ... +1038. Any time code has a textual value like 0.1f, it is encoded to a nearby float, which may not be the exact same text value. The question is: how many digits can we code and still maintain distinctive float?
  2. For the various powers-of-2 range, 223 (8,388,608) values are normally linearly encoded.
  3. Example: In the range [1.0 ... 2.0), 223 (8,388,608) values are linearly encoded.
  4. In the range [233 or 8,589,934,592 ... 234 or 17,179,869,184), again, 223 (8,388,608) values are linearly encoded: 1024.0 apart from each other. In the sub range [9,000,000,000 and 10,000,000,000), there are about 976,562 different values.

Put this together ...

  1. As text, the range [1.000_000 ... 2.000_000), using 1 lead digit and 6 trailing ones, there are 1,000,000 different values. Per #3, In the same range, with 8,388,608 different float exist, allowing each textual value to map to a different float. In this range we can use 7 digits.

  2. As text, the range [9,000,000 × 103 and 10,000,000 × 103), using 1 lead digit and 6 trailing ones, there are 1,000,000 different values. Per #4, In the same range, there are less than 1,000,000 different float values. Thus some decimal textual values will convert to the same float. In this range we can use 6, not 7, digits for distinctive conversions.

The worse case for typical float is 6 significant digits. To find the limit for your float:

#include <float.h>
printf("FLT_DIG = %d\n", FLT_DIG);  // this commonly prints 6

... no idea why we should calculate 2^24 and why we should take log10

224 is a generalization as with common float and its 24 bits of binary precision, that corresponds to fanciful decimal system with 7.22... digits. We take log10 to compare the binary float to decimal text.

224 == 107.22...

Yet we should not take 224. Let us look into how FLT_DIG is defined from C11dr §5.2.4.2.2 11:

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,

p log10 b ............. if b is a power of 10
⎣(p − 1) log10 _b_⎦.. otherwise

Notice "log10 224" is same as "24 log10 2".

As a float, the values are distributed linearly between powers of 2 as shown in #2,3,4.

As text, values are distributed linearly between powers of 10 like a 7 significant digit values of [1.000000 ... 9.999999]*10some_exponent.

The transition of these 2 groups happen at different values. 1,2,4,8,16,32... versus 1,10,100, ... In determining the worst case, we subtract 1 from the 24 bits to account for the mis-alignment.

⎣(p − 1) log10 _b_⎦ --> floor((24 − 1) log10(2)) --> floor(6.923...) --> 6.

Had our float used base 10, 100, or 1000, rather than very common 2, the transition of these 2 groups happen at same values and we would not subtract one.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 2
    Thanks u sir! I have thought about using "map" to deal this problem but I can't think so clearly like u. Your answer really gives me a new way to think this interesting problem. Thank you sincerely. – hello_better Apr 22 '18 at 02:51
4

An IEEE 754 single-precision float has a 24-bit mantissa. This means it has 24 binary bits' worth of precision.

But we might be interested in knowing how many decimal digits worth of precision it has.

One way of computing this is to consider how many 24-bit binary numbers there are. The answer, of course, is 224. So these binary numbers go from 0 to 16777215.

How many decimal digits is that? Well, log10 gives you the number of decimal digits. log10(224) is 7.2, or a little more than 7 decimal digits.

And look at that: 16777215 has 8 digits, but the leading digit is just 1, so in fact it's only a little more than 7 digits.

(Of course this doesn't mean we can represent only numbers from 0 to 16777215! It means we can represent numbers from 0 to 16777215 exactly. But we've also got the exponent to play with. We can represent numbers from 0 to 1677721.5 more or less exactly to one place past the decimal, numbers from 0 to 167772.15 more or less exactly to two decimal points, etc. And we can represent numbers from 0 to 167772150, or 0 to 1677721500, but progressively less exactly -- always with ~7 digits' worth of precision, meaning that we start losing precision in the low-order digits to the left of the decimal point.)

The other way of doing this is to note that log10(2) is about 0.3. This means that 1 bit corresponds to about 0.3 decimal digits. So 24 bits corresponds to 24 × 0.3 = 7.2.

(Actually, IEEE 754 single-precision floating point explicitly stores only 23 bits, not 24. But there's an implicit leading 1 bit in there, so we do get the effect of 24 bits.)

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • thank you for your answer sincerely~ Your answer really helps me a lot!! Thank u sir~ – hello_better Apr 22 '18 at 02:24
  • thank you for your answer sincerely~~Your answer really helps me!! lol~~(eh....It's my first time to use stackoverflow...My comment is hidden and I think I didn't comment successfully so I comment again ^_^ sorry to bother you) – hello_better Apr 22 '18 at 02:25
  • Nice answer, but I would have written "... 0 to 16777215. Any values above 16777215 can also have 7 digits, but are not exactly representable anymore. That is why a range of '6 to 7 digits' is given". – Rudy Velthuis Apr 23 '18 at 16:45
  • @RudyVelthuis Good point. I addressed it in a (perhaps overlong) parenthetical. – Steve Summit Apr 23 '18 at 17:19
-1

Let's start a little smaller. With 10 bits (or 10 base-2 digits), you can represent the numbers 0 upto 1023. So you can represent up to 4 digits for some values, but 3 digits for most others (the ones below 1000).

To find out how many base-10 (decimal) digits can be represented by a bunch of base-2 digits (bits), you can use the log10() of the maximum representable value, i.e. log10(2^10) = log10(2) * 10 = 3.01....

The above means you can represent all 3 digit — or smaller — values and a few 4 digits ones. Well, that is easily verified: 0-999 have at most 3 digits, and 1000-1023 have 4.

Now take 24 bits. In 24 bits you can store log10(2^24) = 24 * log(2) base-10 digits. But because the top bit is always the same, you can in fact only store log10(2^23) = log10(8388608) = 6.92. This means you can represent most 7 digits numbers, but not all. Some of the numbers you can represent faithfully can only have 6 digits.

The truth is a bit more complicated though, because exponents play role too, and some of the many possible larger values can be represented too, so 6.92 may not be the exact value. But it gets close, and can nicely serve as a rule of thumb, and that is why they say that single precision can represent 6 to 7 digits.

Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94