[程式設計] [C_MM05-易] 計算正方形面積以及浮點數的四捨五入

底下主要想解說 C++ 在浮點數運算上,要如何做到「小數點底下 x 位,四捨五入」。所使用的題目是 e-tutor 的 [C_MM05-易] 計算正方形面積

請注意,這兒講的四捨五入,只能在「正數」中使用,遇到負數要另外的解法。

題目

題目簡單來說是這樣的,讓使用者輸入一個「大於0的數」(用浮點數儲存),然後計算「正方形的面積,並輸出」。

所以就是輸出「平方值」即可。

但麻煩在於,這題要求輸出時,要滿足取到「小數點底下一位,並且四捨五入」!

問題

由於我們的電腦對於浮點數只能取進似值,所以有時候會造成浮點數「失真」的情況,例如我們寫 3.25,但在電腦內部被表示為 2.24999999的情況。
(參考資料:comp.lang.c FAQ list · Question 14.1)

這樣一來,就造成四捨五入不精確,而且會隨著編譯器有不同的實作方式

底下是個例子:
程式碼中的 setprecision(1) 以及 fixed 合作後,可以把輸出限制在小數點以下1位,並且四捨五入。但如同前述,由於浮點數的不精確,會造成有時候有四捨五入,有時候沒有。

前述的例子在 Visual Studio,以及 gcc 底下測試,會跑出不同的結果:

Visual Studio
3.15= 3.1 (沒有四捨五入)
3.25= 3.3
3.35= 3.4
3.45= 3.5
3.55= 3.5 (沒有四捨五入)
3.65= 3.6
3.75= 3.8

GCC 6.3 執行的結果 (用 ideone.com 測試)
3.15= 3.1 (沒有四捨五入)
3.25= 3.2 (沒有四捨五入)
3.35= 3.4
3.45= 3.5
3.55= 3.5 (沒有四捨五入)
3.65= 3.6 (沒有四捨五入)
3.75= 3.8

解法

底下的解法參考自 C FAQ ,且只有在正數時有用!

用一個例子來解說,4.5 想要四捨五入到 5.0,那麼你可以這樣做!
floor(4.5+0.5) ==> floor(5.0) == > 5.0

只要加上 0.5 即可。

但要是要小數點以下 x 位呢?
用 3.1515 舉例

如果要小數點以下 1 位
floor(3.1515 * 10 + 0.5) / 10

如果要小數點以下 2 位
floor(3.1515 * 100 + 0.5)/ 100

那3位呢?應該可以推得到,就是乘以 1000 了。

對了,前述的 floor 是無條件捨去的意思。在 C++ 中,請 #include<cmath>,在 C 中,請 #include<math.h>

底下是示範的程式碼:

如此一來,不管在 Visual Studio,或是 GCC 下,都是正確的了。

e-tutor 的部分,就簡單囉,只要把資料讀入,做好平方數後,再用前述想法做4捨5入再輸出即可!

 

留言

這個網誌中的熱門文章

由 Pandas 的 DataFrame 中取得資料

[程式設計] C++ 的字串切割

[程式設計] UVa 介紹,以及 UDebug 和其他輔助工具的介紹