問題
最近我試著在自己的應用中使用四捨五入的值,我和我的用戶在報表應用中的 計算問題存在分歧。所有的代碼都在T-SQL中,但是我認為報表問題與數據類型和 向下取整或向上取整規則關系密切。請問您有沒有這方面的高見?我想看到一些帶 有不同編碼選項的例子。
專家解答
如果不理解基本的數據類型和四捨五入函數,那麼你就可能誤解四捨五入。由 於數據類型的差異(比如integer,float, decimal等等),四捨五入後的值可能 會不同。另外,由於在計算中使用的SQL Server捨入函數(ROUND(),CEILING(), FLOOR())的差異,得到的結果值也可能會不同。因此,找到用戶對四捨五入的要 求接著把這些要求轉化到適當的T-SQL命令中是很重要的。
讓我們先從定義的角度開始:
l ROUND() – 四捨五入一個正數或者負數,結果為一定長度的值。
l CEILING() - 返回最小的整數,使這個整數大於或等於指定數的數值運算。
l FLOOR() - 返回最大整數,使這個整數小於或等於指定數的數值運算。
讓我們來看看有不同數據類型的函數的結果。
ROUND(),CEILING()和FLOOR()例子 例子 值 在這個例子中,你可以看到,在一個正整數的情 況下,這三個捨入函數返回相同的值。 DECLARE @value int SET @value = 6 SELECT ROUND(@value, 1) SELECT CEILING(@value) SELECT FLOOR(@value) 6 6 6 在第二個例子中,即使在一個負整數的情況下, 這三個捨入函數還是返回相同的值。 DECLARE @value int SET @value = -11 SELECT ROUND(@value, 1) SELECT CEILING(@value) SELECT FLOOR(@value) -11 -11 -11 要證明整數這個觀點,四捨五入是不可能的。讓 我們來看看一些其他的數據類型。 DECLARE @value int SET @value = -11.5 SELECT ROUND(@value, 2) SELECT CEILING(@value) SELECT FLOOR(@value) -11 -11 -11 在我們的例子中,用一個小數數據類型和不同長 度參數(比如1,2或者3)的捨入函數會產生不同的終值。當四捨五入這個值並且 長度參數是1時,小數點後第二位的5是有意義的。另外,在小數數據類型中, CEILING和 FLOOR函數也會考慮小數位,因為會得到不同的值。 DECLARE @value decimal(10,2) SET @value = 11.05 SELECT ROUND(@value, 1) SELECT ROUND(@value, 2) SELECT ROUND(@value, 3) SELECT CEILING(@value) SELECT FLOOR(@value) 11.10 11.05 11.05 12 11 如同上面的例子,基於不同的長度參數,小數點 後第二位的6是有意義的。 DECLARE @value decimal(10,2) SET @value = -14.46 SELECT ROUND(@value, 1) SELECT ROUND(@value, 2) SELECT ROUND(@value, 3) SELECT CEILING(@value) SELECT FLOOR(@value) -14.50 -14.46 -14.46 -14 -15 這個例子也有助於描述四捨五入值的破壞。這個 例子也證明了CEILING和 FLOOR 函數四捨五入成最近的函數。 DECLARE @value decimal(10,10) SET @value = .5432167890 SELECT ROUND(@value, 1) SELECT ROUND(@value, 2) SELECT ROUND(@value, 3) SELECT ROUND(@value, 4) SELECT ROUND(@value, 5) SELECT ROUND(@value, 6) SELECT ROUND(@value, 7) SELECT ROUND(@value, 8) SELECT ROUND(@value, 9) SELECT ROUND(@value, 10) SELECT CEILING(@value) SELECT FLOOR(@value) 0.5000000000 0.5400000000 0.5430000000 0.5432000000 0.5432200000 0.5432170000 0.5432168000 0.5432167900 0.5432167890 0.5432167890 1 0 在最後的例子中,你可以看到在浮點數據類型裡 采取與上面小數點的例子相同類型的行為。另外,CEILING和FLOOR函數四捨五入 成最近的函數。 DECLARE @value float(10) SET @value = .1234567890 SELECT ROUND(@value, 1) SELECT ROUND(@value, 2) SELECT ROUND(@value, 3) SELECT ROUND(@value, 4) SELECT ROUND(@value, 5) SELECT ROUND(@value, 6) SELECT ROUND(@value, 7) SELECT ROUND(@value, 8) SELECT ROUND(@value, 9) SELECT ROUND(@value, 10) SELECT CEILING(@value) SELECT FLOOR(@value) 0.1 0.12 0.123 0.1235 0.12346 0.123457 0.1234568 0.12345679 0.123456791 0.123456791 1 0