簡體   English   中英

對於IEEE float,C ++`digits10`是6,但是第一個不可表示的整數已經有8位數?

[英]C++ `digits10` is 6 for IEEE float, but the first non-representable integer already has 8 digits?

C ++的std::numeric_limits<float>::digits10在cppref中描述如下:

std::numeric_limits<T>::digits10的值是可以由類型T表示而沒有更改的基數為10的數字,也就是說,具有此多個十進制數字的任何數字都可以轉換為類型的值T並返回小數形式,不會因舍入或溢出而改變。

C表兄弟FLT_DIG存在類似的描述。

給出的值是:

 float FLT_DIG /* 6 for IEEE float */ 

但是這里顯示的是,在32位IEEE浮點類型中,高達16,777,216 (2 24 )的所有整數都可以精確表示。 如果我能算,這個數字有8位,所以對於價值digits10實際上應該是7,現在不應該嗎?

而是很明顯,我誤解了一些關於digits10這里,那么,這實際上告訴我嗎?


實用性:

有人問我,如果我們能夠從存儲所有號碼0.00 - 86,400.00正是在IEEE 32位浮點。

現在,我非常有信心我們可以在IEEE 32位浮點數中存儲08,640,000所有數字,但這是否適用於向左移動2位數的相同“整數”范圍?

(限制IEEE754 float答案)。

8.589973e98.589974e9都映射到8589973504 這是第7個有效數字被保留的斷言的反例。

由於第6個有效數字上不存在這樣的反例,因此std::numeric_limits<float>::digits10FLT_DIG為6。

實際上,整數可以精確地表示為2的24 冪。( 16,777,21616,777,217都映射到16,777,216 )。 這是因為float具有24位有效數

正如另一個答案和評論所確定的digits10涵蓋了所有“指數范圍”,即它必須保持1234567以及1.23456712345670000 - 這僅適用於6位數!

7位數的反例:

  • 8.589,973 e9 vs. 8.589,974 e9 (來自cppref示例)

有時候很容易找到反例。

#include <stdio.h>
#include <string.h>

int main(void) {
  int p6 = 1e6;
  int p7 = 1e7;
  for (int expo = 0; expo < 29; expo++) {
    for (int frac = p6; frac < p7; frac++) {
      char s[30];
      sprintf(s, "%d.%06de%+03d", frac / p6, frac % p6, expo);
      float f = atof(s);
      char t[30];
      sprintf(t, "%.6e", f);
      if (strcmp(s, t)) {
        printf("<%s> %.10e <%s>\n", s, f, t);
        break;
      }
    }
  }
  puts("Done");
}

產量

<8.589973e+09> 8.5899735040e+09 <8.589974e+09>
<8.796103e+12> 8.7961035080e+12 <8.796104e+12>
<9.007203e+15> 9.0072024760e+15 <9.007202e+15>
<9.223377e+18> 9.2233775344e+18 <9.223378e+18>
<9.444738e+21> 9.4447374693e+21 <9.444737e+21>
<9.671414e+24> 9.6714134744e+24 <9.671413e+24>
<9.903522e+27> 9.9035214949e+27 <9.903521e+27>
<1.000000e+28> 9.9999994421e+27 <9.999999e+27>  This is an interesting one

另一個角度來看:

考慮在每對2的冪之間,像IEEE二進制float編碼線性分布的2 23個值。


示例:介於2 0和2 1或1.0和2.0之間,

float值之間的差異是1.0 / 2 23或10.192e-06。

以文本形式“1.dddddd”(7位數字)編寫,數字相差1.000e-06。

因此,對於十進制文本編號的每一步,大約有10.2 float
編碼這7位數字沒有問題。
在此范圍內,編碼8位數也沒有問題。


示例:介於2 23和2 24或8,388,608.0和16,777,216.0之間。

float值之間的差異是2 23/2 23或1.0。

以文本形式“8or9.ddddd * 10 6 ”(7位有效數字)寫的低端附近的數字相差1.0。

編碼這7位數字沒有問題。


示例:介於2 33和2 34或8,589,934,592.0和17,179,869,184.0之間,

之間的差float值是2 33/2 23或1,024.0。

以文本形式“8or9.ddddd * 10 9 ”(7位有效數字)寫的低端附近的數字相差1,000.0。

現在我們遇到了問題。 從8,589,934,592.0開始,接下來文本形式的1024個數字只有1000個不同的float編碼。


d.dddddd * 10 expo形式的7位數字太多,無法使用float進行唯一編碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM