簡體   English   中英

獲取printf以打印所有浮動數字

[英]Get printf to print all float digits

我對printf("%f", M_PI)的行為感到困惑。 它打印出3.141593 ,但M_PI3.14159265358979323846264338327950288 為什么printf會這樣做,如何讓它打印出整個浮動。 我知道%1.2f格式說明符,但如果我使用它們,那么我得到一堆未使用的0,輸出很難看。 我想要浮子的整個精度,但不是額外的任何東西。

為什么printf會這樣做,如何讓它打印出整個浮動。

默認情況下, printf()函數對%f%F格式說明符的精度為6 從C11(N1570) §7.21.6.1/p8 fprintf函數 (強調我的前進):

如果缺少精度, 則取6 ; 如果精度為零且未指定#flag,則不顯示小數點字符。 如果出現小數點字符,則在其前面至少出現一個數字。 值四舍五入到適當的位數。

因此,呼叫等同於:

printf("%.6f", M_PI);

這與“整個浮動”完全不同,至少不像你想象的那樣直接。 double對象可能以二進制IEEE-754雙精度表示形式存儲。 您可以使用%a%A格式說明符查看確切的表示形式,將其打印為十六進制浮點數。 例如:

printf("%a", M_PI);

將其輸出為:

0x1.921fb54442d18p+1

你可以認為它是“整個浮動”。

如果您需要的是“最長十進制近似”,那么這是有意義的,然后使用<float.h>標頭中的DBL_DIG C11 5.2.4.2.2 / p11 浮動類型的特征

小數位數q,使得帶有q個十進制數字的任何浮點數可以舍入為 p基數為b 的浮點數 ,然后再返回而不更改為q個十進制數字

例如:

printf("%.*f", DBL_DIG-1, M_PI);

可以打印:

3.14159265358979

您可以使用sprintfsprintf打印到具有過度顯示精度的字符串,然后使用函數修剪0s,然后使用%s將字符串傳遞給printf以顯示它。 概念證明:

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

void trim_zeros(char *x){
    int i;
    i = strlen(x)-1;
    while(i > 0 && x[i] == '0') x[i--] = '\0';
}

int main(void){
    char s1[100];
    char s2[100];
    sprintf(s1,"%1.20f",23.01);
    sprintf(s2,"%1.20f",M_PI);
    trim_zeros(s1);
    trim_zeros(s2);
    printf("s1 = %s, s2 = %s\n",s1,s2);
    //vs:
    printf("s1 = %1.20f, s2 = %1.20f\n",23.01,M_PI);
    return 0;
}

輸出:

s1 = 23.010000000000002, s2 = 3.1415926535897931
s1 = 23.01000000000000200000, s2 = 3.14159265358979310000

這表明這種方法可能不是你想要的。 如果小數部分中的連續零的數量超過一定長度(可以作為參數傳遞給trim_zeros而不是簡單地修剪零,您可能希望截斷。另外 - 您可能希望確保23.0顯示為23.0而不是23.(所以也許在小數點后保留一個零)。這主要是概念證明 - 如果你對printf使用sprintf不滿意,那么按摩結果。

將一段文本轉換為浮點數或雙精度數后,“全部”數字不再是有意義的概念。 例如,計算機無法知道它轉換為“3.14”或“3.14000000000000000275”,並且它們都碰巧產生了相同的浮點數。 根據您對所涉及數字精確度的了解,您只需選擇適合您任務的位數即可。

如果要打印盡可能多的數字,可能會被格式清楚地表示,浮點數約為7位數,雙數約為15,但這是近似值。

暫無
暫無

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

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