float浮點數的四舍五入


 

前幾天,有個小伙伴在做實驗過程中,發現了一個奇怪的現象,這個現象就是…

他在用printf輸出浮點數的時候,想把數據保留到小數點后的兩位,他是這么寫的…

float c=1.155;printf(“%.2f”,c);

他的書寫是對的,沒有錯誤。但是他發現,當c等於1.555時,保留兩位小數輸出是1.55,而當c等於3.555時,保留兩位小數輸出是3.56。這個結果,就讓人捉摸不透了,因為…

如果是程序運算會自動四舍五入的話,結果應該是1.56和3.56;如果程序運算不會自動四舍五入的話,結果應該是1.55和3.55。可是結果卻是1.55和3.56,這是什么鬼?

如果你去百度輸入關鍵詞“浮點數 四舍五入”,你會發現,有些人會說浮點數會自動四舍五入,如下圖…

浮點數會自動四舍五入1

而有些人會說,不會自動四舍五入,如下圖…

浮點數會自動四舍五入2

到底會不會自動四舍五入呢?

我剛才拿老頑童STM32開發板做了一個實驗,我定義了6個浮點數,他們分別是…

浮點數會自動四舍五入3

然后我用printf給他們保留2位小數后輸出,程序如下…

浮點數會自動四舍五入4

在串口調試助手上看到的結果是…

浮點數會自動四舍五入5

結果是,6個數,有3個數自動四舍五入了,有3個數沒有四舍五入。

不管理論是什么,我們只看結果。結果是:浮點數保留小數點后的數據,有時會自動四舍五入,有時不會自動四舍五入。但是…

如果把一個浮點數賦給一個整數變量后,一定不會四舍五入。

所以,我們在保留浮點數的小數點精度時,必須要人工處理四舍五入

很多人一直在用的一個的方法,就是加0.5法

這個方法的理論依據是:

float f;//定義了一個浮點數

int t;//定義了一個整數

我們執行(t=f;)這條語句,不管f的小數點后面是小於5的數,還是大於等於5的數,都不會四舍五入,例如當f=3.2和f=3.8,結果都是t=3。

那么怎么樣讓f=3.8時,t=4呢?我們可以給f+0.5來解決,例如當f=3.8時,f+0.5=4.3,執行完t=f后,t就等於4了。而當f的小數點后的的數都小於5時,加一個0.5不會大於4,所以執行完t=f后,結果還都是3。這正好符合我們四舍五入的要求。

這里需要注意的是:其實這個…

加0.5的方法

只適合用於保留整數位的應用

很多人都不知道這一點,下面我就給大家實踐一下。

按照加0.5法的原理,如果要保留2位有效數據的話,需要給數據加0.005,我們做個實驗,把temp1~6都加0.005。

浮點數會自動四舍五入6

然后我們看輸出結果,如下圖…

浮點數會自動四舍五入7

看到了正確的結果,你不要高興,因為…

你現在可以把temp1~6的小數點后面都改為554,如下圖…

浮點數會自動四舍五入8

這時候,正確的結果,小數點后兩位應該都是55,但是你看看結果,還是照樣是56。這時候,就輸出了完全錯誤的結果。

有的朋友會說,既然加0.005不行,那我們想辦法還是加0.5吧。好的,下面我有一個方法…

先把temp1*100,然后再+0.5,然后把這個浮點數賦值給一個整數,然后再把這個整數除以100。

例如temp5的程序寫為…

temp5=temp5*100+0.5;

t5=temp5;

temp5=(float)t5/100;

其中,t5是我定義的一個uint32_t類型的整型變量。我們來分析一下,因為temp5=4.555,4.555乘以100以后是455.50,然后再加0.5以后是456.00,把456.00取整后是456,然后456除以100就是4.56。

一切都算計的很好,但是實際的結果卻還是4.55。但是如果你這樣寫的話,結果就是正確的…

temp5=4.555*100+0.5;

t5=temp5;

temp5=(float)t5/100;

看這個程序和上邊的程序對比一下,只是這里直接用了4.555,而上邊的程序用了temp5,看似一樣,結果卻不一樣。上邊程序的結果是4.55,下邊程序的結果是4.56。

上邊兩個加0.5的實踐,你一定要試一下。

那保留2位小數,怎么做才能確保完全正確?

送給大家一句話:捷徑有可能是歧途,最笨的辦法,其實是最保險的辦法。(頑童哥語錄一定要收藏)

我們可以把小數點后的第三位數取出來,然后判斷它和5的大小,然后四舍五入。就是這個方法,絕對正確。寫成程序的話,是這個樣子的…

浮點數會自動四舍五入9

其中,t1是定義的uint32_t類型的整型變量。我們把數據帶進去看一下,temp1是0.555,0.555乘以1000是555,555除以100取余數是55,55再除以10取余數是5,那t1就等於5。下面用if語句判斷是否要進位,如果需要進位的話,4.555乘以100就是455.5,455.5加1就是456.5,然后我們把456.5強制類型轉換成整型數據,就是456,456除以100,就是4.56;如果不需要進位的情況,大家自行分析。

這時候,你去換temp1~6的值去吧,不管換什么,結果都會四舍五入。

做一個穩定的電子產品,基礎知識很重要!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM