[英]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
旨在產生對許多目的來說足夠准確的文本表示,但不會過於冗長和煩人。
將float
或double
標記為具有 7 或 15 位數字最多只是一個粗略的估計,不應用作任何類型的精度數值分析。
要評估精度和數值效果,您應該始終將float
和double
類型視為具有 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
(對於典型的float
和double
格式分別為 9 和 17),並非旨在衡量精度。 它們本質上是為了解決這個問題:
它不是浮點格式准確性的衡量標准。 它包括一些由二進制和十進制之間的差異引起的“額外”數字,以允許它們在某種意義上“偏移”並且不對齊。 就好像你有一個奇怪的盒子,你想把它放進一個長方形的盒子里——你需要一個實際上比奇怪的盒子有更大面積的盒子,因為它不完美。 同樣, max_digits10
指定的十進制位數比浮點類型的實際信息內容多。 所以它不是類型精度的正確度量。
>::radix and std::numeric_limits< >::digits
.為您提供類型精度信息的參數是std::numeric_limits< >::radix
和std::numeric_limits< >::digits
。 第一個是用於浮點的數字基數,在常見的 C++ 實現中為 2。 第二個是浮點類型的位數。 這些是浮點格式中使用的實際數字; base- digits.它的有效數字是由組成的數字。 例如,對於常見的float
和double
類型, radix
為 2, digits
為 24 或 53,因此它們分別使用 24 個 base-two 和 53 base-two 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.