2013-02-25 23 views
0

我想在gcc/Linux移植版本的Windows軟件中實現完全相同的浮點結果。出於這個原因,我希望所有的雙重操作都是64位精度。這可以使用例如-mpc64或-msse2或-fstore-floats(全部帶有副作用)來完成。然而,我無法解決的一件事是超驗函數,如sin/asin等。文檔說,他們內部期望(並使用我認爲)的長雙精度,無論我做什麼,他們產生的結果都與Windows相同。gcc和sin/cos /超越函數在Windows中的精確度如下

這些函數如何使用64位浮點精度計算結果?

更新:我錯了,它是printf(「%。17f」),錯誤地舍入正確的雙重結果,gdb中的「print x」顯示數字本身是正確的。我想我需要一個關於這個問題的不同問題......也許關於如何讓printf不把內部對象看作擴展對象。也許使用stringstream會給出預期的結果......是的。

+0

您是否使用Microsoft的編譯器編譯Windows的所述軟件?什麼是編譯選項w.r.t.浮點?這裏有幾個選項,請參閱'精確'的[Microsoft Visual C++浮點優化](http://msdn.microsoft.com/en-us/library/aa289157%28v=vs.71%29.aspx) ,「快速」,「嚴格」等。另外,你可以看看這兩個版本的反彙編,看看他們有什麼不同嗎? – 2013-02-25 08:31:21

+0

您可以確定這些函數不是使用標準庫實現者的查找表來實現的嗎? – Bingo 2013-02-25 08:47:20

+1

它是用_precise_編譯的,文檔說:「中間表達式是以默認的53位精度計算的」。至於查找表等,我不知道。但是gcc的文檔說:「請注意,一些數學庫假設默認情況下啓用了擴展精度(80位)浮點操作;這些庫中的例程可能會嚴重損失準確性,通常是通過所謂的」災難性消除「,這個選項[mpc64]用於將精度設置爲小於擴展精度。」 (c)gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html – queen3 2013-02-25 09:08:27

回答

0

不同的LibM庫對基本功能使用不同的算法,因此您必須在Windows和Linux上使用相同的庫才能獲得完全相同的結果。我建議編譯FDLibM並將其與您的軟件靜態鏈接。

0

當我使用stringstream < < setprecision(17)時,我發現它是printf(「%17f」),它使用不正確的精度打印結果(可能在內部擴展)。所以答案並不是真的與問題有關,但至少它適用於我。

但是,如果有人提供了一種讓printf產生預期結果的方法,我會很高興。

+0

大約一年前,你問了下面鏈接的問題,並總結了那裏的答案,不會有Linux修復這個問題,因爲Windows錯了,Linux是正確的。現在你所說的話聽起來非常非常類似於你當時所說的話。是什麼讓你覺得這不再是同一個「問題」? HTTP://計算器。com/questions/9496396/gcc -double-printf-precision-wrong-output – 2013-02-27 19:29:37

+0

這是一個完全不同的問題。那一個是Windows忽略了大於17的精度,而gcc沒有。將gcc限制爲.17後,我在那裏得到了相同的結果。這一點是相同的.17精度和gcc產生不同的結果。實際上,甚至在gcc上使用setprecision(17)和printf(「%。17g」)的串流也會產生不同的結果。 – queen3 2013-02-28 08:40:41

0

超越函數問題的一個很好的解決方案是使用GNU MPFR庫。但請注意,Microsoft編譯器不支持擴展精度浮點。使用Microsoft編譯器,double和long double都是53位精度。使用gcc,long double是64位精度。要在Windows/Linux上獲得匹配結果,您必須避免使用long double或避免使用Microsoft編譯器。對於許多Windows項目,gcc(mingw)的Windows端口運行良好。這可以讓Windows項目使用64位精度長雙打。 mingw長時間雙重支持的一個問題是,mingw使用Microsoft庫進行printf等調用。出於這個原因,打印一個長整倍數不能正常工作。解決此問題的方法是使用mpfr_printf。