[程式設計] [C_MM05-易] 計算正方形面積以及浮點數的四捨五入
底下主要想解說 C++ 在浮點數運算上,要如何做到「小數點底下 x 位,四捨五入」。所使用的題目是 e-tutor 的 [C_MM05-易] 計算正方形面積。
請注意,這兒講的四捨五入,只能在「正數」中使用,遇到負數要另外的解法。
所以就是輸出「平方值」即可。
但麻煩在於,這題要求輸出時,要滿足取到「小數點底下一位,並且四捨五入」!
(參考資料: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
用一個例子來解說,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入再輸出即可!
請注意,這兒講的四捨五入,只能在「正數」中使用,遇到負數要另外的解法。
題目
題目簡單來說是這樣的,讓使用者輸入一個「大於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入再輸出即可!
留言
張貼留言