簡體   English   中英

C++ 中的 float、double 或 long double 的精度是什么意思?

[英]What does the precision of float, double or long double mean in C++?

例如,在此表中,他們說 7 位浮點數和 15 位雙精度數: https://docs.microsoft.com/en-us/cpp/cpp/data-type-ranges

但是這個語句返回 9:

std::cout << std::numeric_limits<float>::max_digits10 << '\n';

添加此返回 17:

std::cout << std::numeric_limits<double>::max_digits10 << '\n';

也許我們應該從數字中減去 + 或 - 號和點? 在這里他們說這個精度是保證數字在文本->數字->文本轉換后保留: https://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10

但是當我這樣做時,精度總是7,在雙精度的情況下:

#include <iostream>
#include <string>
int main() {
  double d_example = 0.123456789;
  std::string str_example = std::to_string(d_example);
  d_example = stod(str_example);
  std::cout << str_example << '\n';
  std::cout << d_example << '\n';
}

這些數字是不同操作的特征。

最大十進制數字( numeric_limits<>::max_digits10 ):如果將浮點數轉換為具有至少那么多十進制數字的字符串(不包括句點等非數字字符),然后返回數字,則結果數量保證與原件相同。

十進制數字( numeric_limits<>::digits10 ):如果一個字符串最多有那么多十進制數字(不包括非數字字符,如句點)被轉換為浮點數,然后再轉換回具有相同數字的字符串十進制數字,結果字符串保證表示與原始字符串相同的數字。

單精度浮點數的十進制數字值實際上是 6,而不是 7。有時非正式地給出為 7,因為測試對於大多數7 位字符串都會成功。

您鏈接的max_digits10頁面上,有一個示例將float值按最小可表示增量,並使用std::setprecision setprecision 和<<顯示它以進行流式傳輸,其中 output 包括:

   max_digits10 is 9 digits
submax_digits10 is 8 digits
 
[...]
 
   max_digits10: 10.0000095
submax_digits10: 10.00001
 
   max_digits10: 10.0000105
submax_digits10: 10.00001

在那里,您會看到兩個float值 - 如果使用max_digits10精度顯示 - 將四舍五入為 10.0000095 和 10.0000105。 如果您使用少一個數字來顯示它們(這是 output 的下一行顯示的內容,為簡潔起見,只是丟棄尾隨的 0),您將獲得相同的 10.00001[0] 兩個float值文本,因此無法如果您將文本流式傳輸回float變量,則重新創建原始float值。 這就是max_digits10的意義——這種可逆的序列化——如果你使用那個位數的話。

但是,您的代碼使用std::to_string ,它使用的默認精度小於max_digits10 to_string旨在產生對許多目的來說足夠准確的文本表示,但不會過於冗長和煩人。

floatdouble標記為具有 7 或 15 位數字最多只是一個粗略的估計,不應用作任何類型的精度數值分析。

要評估精度和數值效果,您應該始終將floatdouble類型視為具有 24 位和 53 位精度的二進制數字,因為這就是它們的實際表示方式。 二進制和數字表示在各種方面是不相稱的,因此試圖理解或分析十進制的行為使得很難理解二進制效果。

>::max_digits10 , which are 9 and 17 for the typical float and double formats, are not intended to be measures of precision.您正在查看的數字std::numeric_limits< >::max_digits10 (對於典型的floatdouble格式分別為 9 和 17),並非旨在衡量精度。 它們本質上是為了解決這個問題:

  • 我需要將十進制的浮點數寫入文件,然后將文件中的十進制數讀回浮點數。 我需要寫多少個十進制數字才能保證讀回它會恢復原始數字?

不是浮點格式准確性的衡量標准。 它包括一些由二進制和十進制之間的差異引起的“額外”數字,以允許它們在某種意義上“偏移”並且不對齊。 就好像你有一個奇怪的盒子,你想把它放進一個長方形的盒子里——你需要一個實際上比奇怪的盒子有更大面積的盒子,因為它不完美。 同樣, max_digits10指定十進制位數比浮點類型的實際信息內容多。 所以它不是類型精度的正確度量。

>::radix and std::numeric_limits< >::digits .為您提供類型精度信息的參數是std::numeric_limits< >::radixstd::numeric_limits< >::digits 第一個是用於浮點的數字基數,在常見的 C++ 實現中為 2。 第二個是浮點類型的位數。 這些是浮點格式中使用的實際數字; base- digits.它的有效數字是由組成的數字。 例如,對於常見的floatdouble類型, radix為 2, digits為 24 或 53,因此它們分別使用 24 個 base-two 和 53 base-two 。

暫無
暫無

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

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