2010年8月20日 星期五

整數除以整數結果竟然只保留整數,那小數呢?

最近剛好遇到前端程式與後端資料庫計算後差一塊的問題,應是資料庫端四捨五入的地方怪怪,仔細一看T-SQL語法,整數除整數,比如說51/100,不是0.51嗎?那我用ROUND(51/100,0),應該會進位後得到1吧,結果居然是0,讓我傻眼了一下,那我直接在SSMS中,實際先下了select 51/100看看,結果真的是0,有圖有真相
我想說難道我誤設了什麼,讓資料庫自動幫我捨去小數點嗎?我查了一下,好像沒有這個設定啊,怪怪

後來經查看了SQL Server 2005 線上叢書(BOL)後,終於真相大白,在BOL中的資料類型優先順序中有提到,擷取內容如下:

當一個運算子結合兩個不同資料類型的運算式時,資料類型優先順序的規則,會指定將低優先順序的資料類型,轉換為高優先順序的資料類型。如果轉換不是支援的隱含轉換,就會傳回錯誤。如果這兩個運算元運算式的資料類型相同,則作業結果就含有該資料類型。

所以當整數除以整數,因為除法運算子結合兩個運算元都是整數的資料類型,所以結果就會是整數囉

那在BOL的/ (除法)中也提到,擷取內容如下:

結果類型傳回優先順序較高之引數的資料類型。如果是整數 dividend 除以整數 divisor,結果就是整數,結果的任何小數點後數字部份都會截斷。

看到這,應能理解select 51/100會回傳0是正常的吧

那整數除以整數的結果想保留小數位數要怎麼作呢?
利用資料類型的優先順序囉,把除法運算子左右兩旁的整數,其中一個轉換為浮點數,這時因為運算子結合了整數與浮點數,隱含的轉換會將整數轉換為浮點數,為什會轉換成浮點數呢,是因浮點數的優先順序高於整數,最後結果就是浮點數囉,當然左右整數都先強制轉換為浮點數最好囉

示範語法如下
select 1.0*51/100, 51/(1.0*100),cast(51 as float)/100,cast(51 as float)/cast(100 as float)


前面兩種乘1.0的是我在網路上看到有人這樣做,各位可以注意一下,1.0成的是前面的整數還是後面整數,小數位數竟然不一樣喔,後面兩種就都一樣,自己判斷哪種好用吧

0 意見:

張貼留言