iT邦幫忙

DAY 4
3

程式設計心法系列 第 4

程式設計心法:3.資料型別--浮點數

浮點數!好困難喔!每次都搞不懂甚麼叫倍精數,甚麼叫做單精數!O_o?

對的,在電腦 0 與 1 的世界中,要表現出無限小數是有其困難點與複雜度的。一般我們在計算小數點幾位的精確度,頂多也只到小數點 5, 6 位而已,如單價低的貨品,需要賣出大量的貨才會有利潤,這時候你的單價可能需要準確到小數點第五位,但這對電腦來說也是輕而易舉的事情。

那複雜的是甚麼呢?

如果您是要計算天文的距離,這時候小數點的精確度問題就會浮現,正所謂 失之毫釐 差之千里,就是這個意思。

OK,讓我們進入浮點數的單元吧!
.避免對相差懸殊的數做加減運算
當您在做以下的運算時,可能會得不到正確的結果,
1000000.00+0.01 可能會得到1000000.00的結果
不過這是以前的程式語言中可能發生的問題,現在的Compiler對這個部份都可以做到很好的運算結果。
我們也可以將小數整數化,透過長整數來做運算,如:
(1000000*100+0.01*100)/100
這個觀念,我們在底下的四捨五入中會使用到。

.避免做"等於"的比較運算
看起來應該是相等的兩個浮點數,可能會有不相等的結果!這是因為,用不同的方法所製造出來的浮點數的值不見得一定相等。書中的例子,0.1加十次不一定會是1.0

dim Nominal as single
dim Sum s single
dim i as integer

Nominal=1.0

Sum=0

for i=1 to 10
  Sum=Sum+0.1
next i
if Nominal=Sum then
  Msgbox "兩個數是相同的"
else
  Msgbox "兩個數是不同的"
end if

這樣可能得到兩個數是不相同的結果
我們可以透過以下的方式來避免這個問題

const AcceptableDelta=0.00001

if abs(Nominal-Sum)<AcceptableDelta then
  Msgbox "兩個數是相同的"
else
  Msgbox "兩個數是不同的"
end if

或者使用內建比較函數 equals 來做為比較的運算
if Nominal.equals(Sum)

.避免四捨五入的誤差
四捨五入的問題,跟前一段所提的問題很類似,撇開書中所舉的例子,我要來談談實際運用面如何解掉一些可能發生的問題。

四捨五入有很困難嗎?不是都有提供四捨五入的函數,例如 Round?

是這樣沒錯,但是您知道他的運作原理嗎?

一般我們要取小數兩位的數時,我們通常會這樣寫

x=round(y,2)

就數學上的運算來說,四捨五入就是 +0.5 做無條件捨去
我們要取小數點兩位,可以做如下的運算

dim x as single

x=Cint(y*100+0.5)
x=x/100

這樣就可以避免掉浮點數計算中可能會遇到的誤差問題

其實,這個觀念是我的大師兄告訴我的,當初聽到的時候,真是如獲至寶,果然是大師兄才會得到師父的真傳(回憶中...)

回神啦!趕快去準備明天的進度啦!

本系列文章


上一篇
程式設計心法:2.資料型別--整數
下一篇
程式設計心法:4.資料型別--字元與字串
系列文
程式設計心法31
0
海綿寶寶
iT邦大神 1 級 ‧ 2009-10-10 10:07:48

國慶日耶
一大早就上電腦概論...

這麼專業的東西
還是交給panc328大大來comment吧...

jamesjan iT邦高手 1 級 ‧ 2009-10-10 13:37:13 檢舉

今天是國慶?
Sorry 最近只專注在因應大陸十一長假的議題
都忘了...XD

0
fillano
iT邦超人 1 級 ‧ 2009-10-10 10:15:47
jamesjan iT邦高手 1 級 ‧ 2009-10-10 13:35:38 檢舉

感謝 fillno 大的補充 ^^

0
pantc328
iT邦研究生 1 級 ‧ 2009-10-10 11:43:48

我以前在公司討論Float重點是在非常非常小的值的情形下.
如果以資料庫來說.一般寫沖帳的程式,如果在int情形下數值等於0的時候表示這一筆交易已被結案.但如果是Float情形下可能剩餘值不等於但趨近於0的情形.所以你要做趨近於0為結案的算法.
而就資料庫而言在值趨近於0時,這個值會是一個不確定的值.他會在某個區間值.所以在查詢時可能下條件不是=而要下A>=值<=B.

另外已Float去做大數值的運算.結果會有某些偏差.比如說小數幾位下x好幾百億的值後結果就不正確.那時候我們老闆有舉例.好像做國防部的案子,資金好幾百億,在做利息運算時.最後的金額跟原本的金額只差幾塊錢而已就會出現問題.

所以說科學中可以用Float.在商業程式還是用Decimal 或Money去存.雖然空間浪費較大.但結果較精準.

jamesjan iT邦高手 1 級 ‧ 2009-10-10 13:32:23 檢舉

我目前只處理過幾十億的 case ...XD
pantc328 大說得沒錯,在商業環境的資料庫中,還是以 decimal 或 numeric 的型態為主

我要留言

立即登入留言