我有一個ASCII「15605632.68128593」我希望 其轉換爲雙不失準確性因素 -ATOF精度與雙造成的悲痛
so
double d;
d=(double)atof("15605632.68128593");
printf("%f",d);
printed result is 15605632.681286
任何想法?
謝謝 - !
我有一個ASCII「15605632.68128593」我希望 其轉換爲雙不失準確性因素 -ATOF精度與雙造成的悲痛
so
double d;
d=(double)atof("15605632.68128593");
printf("%f",d);
printed result is 15605632.681286
任何想法?
謝謝 - !
很可能你沒有得到所有的尾隨小數位。嘗試printf("%.8f", d)
。
您也可以嘗試sscanf("15605632.68128593", "%lf", &d)
來代替atof
調用。
也沒有必要將atof
的結果轉換爲double
。這已經是雙倍了。但演員沒有傷害。
請注意 - 至少大約6年前,當我仔細查看這個時 - 許多printf
和scanf
實現都是錯誤的,因爲它們並不像您所假設的那樣起到完美反轉的作用。 Visual C/C++和gcc在其本地實現中都遇到了問題。 This paper是一個有用的參考。
Cygwin的用gcc 4.3.4:
#include <stdio.h>
int main(void)
{
double x;
sscanf("15605632.68128593", "%lf", &x);
printf("%.8f\n", x);
return 0;
}
然後:
# gcc foo.c
# ./a
15605632.68128593
它工作正常! - 謝謝基因.. –
然後你應該通過點擊複選標記來接受答案。 –
double
沒有那麼多的精度。它只能從十進制字符串到double
返回十進制字符串,將15(DBL_DIG
從float.h
)小數點後的位置返回十進制字符串。
編輯:雖然,一般來說,我的聲明是真實的,但在這裏似乎並不是你的問題。雖然存在不能被四捨五入的16位小數位數,但這個特定輸入可以。
目標:將「15605632.68128593」轉換成雙精度不失準確性。
atof()
實現了最好的程序可以做到的。但由於15605632.68128593
(16位數字)並非,因此您的C
中的可表示爲double
,因此它近似爲1.560563268128593080...e+07
。因此準確性失去了,儘管損失很小。
double
Typical可以代表約2 不同的號碼。附近的候選人和OP的字符串如下所示供參考。
15605632.68128592893... previous double
"15605632.68128593"
15605632.68128593080... closest double
悲痛來嘗試進行打印時,認爲什麼是印刷的x
的確切值。而是打印了一個四捨五入的值。使用%f
說明符默認爲'。'右側的6個位置。給出報告15605632.681286
,一個14位數字。
查看所有double
的所有有效數字的更好方法是使用%e
格式和DBL_DIG
。 DBL_DIG
是'。'的最右邊數字,用十進制指數表示法%e
來顯示「往返」a所需的所有數字double
(將字符串加倍爲不帶字符串差異的字符串)。由於%e
始終在'。'的左側顯示1位數字,因此下面的圖顯示1 + DBL_DIG
有效數字。 DBL_DIG
是我的礦井和許多C
環境,但它有所不同。
如果你想顯示所有的顯著數字,你需要什麼樣的資格是顯著。 nextafter()
函數顯示下一個可表示的double
。所以我們可能想要顯示至少足夠的數字來區分x和下一個x。我建議DBL_DIG + 2
。儘管DBL_DIG
可能就足夠了。 Details
的確切值用於您"1.560563268128593e+07"
程序是15605632.68128593079745769500732421875
。有幾種情況需要查看所有這些數字。即使你要求很多數字,在某些時候,printf()
只是給你零。
#include <stdio.h>
#include <float.h>
#include <tgmath.h>
int main(int argc, char *argv[]) {
double x;
x = atof("15605632.68128593");
printf("%.*le\n",DBL_DIG, x); // All digits "round-trip" string-to-double-string w/o loss
printf("%.*le\n",DBL_DIG + 1, x); // All the significant digit "one-way" double-string
printf("%.*le\n",DBL_DIG + 1, nextafter(x, 2*x)); // The next representable double
printf("%.*le\n",DBL_DIG + 3, x); // What happens with a few more
printf("%.*le\n",DBL_DIG + 30, x); // What happens if you are a bit loony
return 0;
}
1.560563268128593e+07
1.5605632681285931e+07
1.5605632681285933e+07
1.560563268128593080e+07
1.560563268128593079745769500732421875000000000e+07
是的,它只是一個印刷問題 - 但它造成了我很多問題..謝謝 –
d = atof(「15605632.68128593」);這應該是x = atof(「15605632.68128593」) –
@alirezasanaee謝謝 - 發佈修改 – chux
閱讀printf的文檔...「F,F 雙參數呈圓形,並且在風格轉換爲十進制表示[ - ] ddd.ddd,其中位數小數點後的字符等於精度規格,如果精度丟失,則取爲6「 –