Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
330 views
in Technique[技术] by (71.8m points)

c - Why floating-points number's significant numbers is 7 or 6

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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. 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 trailings 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 trailings 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
", FLT_DIG);  // this commonly prints 6

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

2^24 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...