亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

啟用優化的不同浮點結果-編譯器錯誤?

啟用優化的不同浮點結果-編譯器錯誤?

C++
德瑪西亞99 2019-11-29 09:16:00
以下代碼在經過優化和未經優化的情況下都適用于Visual Studio 2008。但是,它僅適用于未經優化(O0)的g ++。#include <cstdlib>#include <iostream>#include <cmath>double round(double v, double digit){    double pow = std::pow(10.0, digit);    double t = v * pow;    //std::cout << "t:" << t << std::endl;    double r = std::floor(t + 0.5);    //std::cout << "r:" << r << std::endl;    return r / pow;}int main(int argc, char *argv[]){    std::cout << round(4.45, 1) << std::endl;    std::cout << round(4.55, 1) << std::endl;}輸出應為:4.54.6但是帶有優化(O1- O3)的g ++ 將輸出:4.54.5如果我volatile在t之前添加關鍵字,那么它會起作用,那么是否可能存在某種優化錯誤?在g ++ 4.1.2和4.4.4上進行測試。這是在ideone上的結果:http ://ideone.com/Rz937我在g ++上測試的選項很簡單:g++ -O2 round.cpp更有趣的結果是,即使我/fp:fast在Visual Studio 2008 上啟用了選項,結果仍然是正確的。進一步的問題:我想知道,是否應該始終打開該-ffloat-store選項?因為我測試的g ++版本隨CentOS / Red Hat Linux 5和CentOS / Redhat 6一起提供。我在這些平臺上編譯了許多程序,我擔心它會導致程序內部出現意外錯誤。研究我所有的C ++代碼和使用的庫是否存在此類問題似乎有點困難。有什么建議嗎?是否有人對為什么即使/fp:fast打開Visual Studio 2008仍然可以工作感興趣?似乎Visual Studio 2008在此問題上比g ++更可靠?
查看完整描述

3 回答

?
慕仙森

TA貢獻1827條經驗 獲得超8個贊

英特爾x86處理器內部使用80位擴展精度,而double通常為64位寬。不同的優化級別會影響來自CPU的浮點值保存到內存的頻率,從而從80位精度四舍五入到64位精度。


使用-ffloat-storegcc選項可獲得具有不同優化級別的相同浮點結果。


或者,使用long double通常在gcc上為80位寬的類型,以避免精度從80位舍入到64位。


man gcc 全部說明:


   -ffloat-store

       Do not store floating point variables in registers, and inhibit

       other options that might change whether a floating point value is

       taken from a register or memory.


       This option prevents undesirable excess precision on machines such

       as the 68000 where the floating registers (of the 68881) keep more

       precision than a "double" is supposed to have.  Similarly for the

       x86 architecture.  For most programs, the excess precision does

       only good, but a few programs rely on the precise definition of

       IEEE floating point.  Use -ffloat-store for such programs, after

       modifying them to store all pertinent intermediate computations

       into variables.


查看完整回答
反對 回復 2019-11-29
?
婷婷同學_

TA貢獻1844條經驗 獲得超8個贊

輸出應為:4.5 4.6如果您具有無限精度,或者正在使用使用基于十進制而不是基于二進制的浮點表示的設備,那么輸出就是這樣。但是,事實并非如此。大多數計算機使用二進制IEEE浮點標準。


正如Maxim Yegorushkin在回答中指出的那樣,部分問題是計算機內部使用的是80位浮點表示形式。不過,這只是問題的一部分。問題的基礎是n.nn5形式的任何數字都沒有確切的二進制浮點表示形式。這些極端情況總是不精確的數字。


如果您確實希望舍入能夠可靠地舍入這些極端情況,則需要一種舍入算法來解決以下事實:n.n5,n.nn5或n.nnn5等(而不是n.5)始終是不精確。找到確定某些輸入值是向上舍入還是向下舍入的特殊情況,并根據與該特殊情況的比較返回四舍五入后的值。而且,您確實需要注意,優化的編譯器不會將找到的特殊情況放入擴展的精度寄存器中。


請參閱即使不精確,Excel如何如何成功舍入浮點數?對于這樣的算法。


或者,您可以忍受極端情況有時會錯誤舍入的事實。


查看完整回答
反對 回復 2019-11-29
?
手掌心

TA貢獻1942條經驗 獲得超3個贊

不同的編譯器具有不同的優化設置。根據IEEE 754的規定,某些較快的優化設置未維護嚴格的浮點規則。Visual Studio中有一個特定的設置,/fp:strict,/fp:precise,/fp:fast,其中/fp:fast違反了什么可以做標準。您可能會發現,標志是控制此類設置中的優化的因素。您可能還會在GCC中找到類似的設置,該設置會更改行為。

如果是這種情況,則編譯器之間的唯一不同之處在于,默認情況下,GCC會在更高的優化條件下尋找最快的浮點行為,而Visual Studio不會在更高的優化級別下更改浮點行為。因此,它不一定是實際的錯誤,而是您不知道要打開的選項的預期行為。


查看完整回答
反對 回復 2019-11-29
  • 3 回答
  • 0 關注
  • 649 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號