爲了提供一些背景知識,我目前正在開發一個將Access數據庫及其代碼轉換爲SQL的項目。Float數據類型將不會與銀行家四捨五入 - SQL Server 2008
在此過程中,我在SQL Server中將Access數據類型Double
更改爲Float
;我這樣做是因爲這些數據類型是密切相關的,因爲我的數據庫執行了很多分割和乘法(我聽說漂浮最適合)。
轉換數據庫的另一個問題出現在Access使用銀行家四捨五入的事實,而SQL沒有;我走出去,發現兩個UD銀行家四捨五入的功能,都沒有讓一致的銀行家圓滿結果,因爲他們應該。
這是不一致的東西,當我試圖運行這些銀行家四捨五入的功能(其中包括減法和加法)浮點數時,我應該期望嗎?
以下是這兩個功能......
FUNCTION [dbo].[RB](@Val FLOAT, @Digits INT)
RETURNS FLOAT
AS
BEGIN
RETURN CASE WHEN ABS(@Val - ROUND(@Val, @Digits, 1)) * POWER(10, @Digits+1) = 5
THEN ROUND(@Val, @Digits, CASE WHEN CONVERT(INT, ROUND(ABS(@Val) *
POWER(10,@Digits), 0, 1)) % 2 = 1 THEN 0 ELSE 1 END)
ELSE ROUND(@Val, @Digits)
END
END
FUNCTION [dbo].[RoundBanker]
(@Amt NUMERIC(38,16)
, @RoundToDecimal TINYINT
)
RETURNS NUMERIC(38,16)
AS
BEGIN
DECLARE @RoundedAmt NUMERIC(38,16)
, @WholeAmt INT
, @Decimal TINYINT
, @Ten NUMERIC(38,16)
SET @Ten = 10.0
SET @WholeAmt = ROUND(@Amt,0, 1)
SET @RoundedAmt = @Amt - @WholeAmt
SET @Decimal = 16
WHILE @Decimal > @RoundToDecimal
BEGIN
SET @Decimal = @Decimal - 1
IF 5 = (ROUND(@RoundedAmt * POWER(@Ten, @Decimal + 1) ,0,1) -
(ROUND(@RoundedAmt * POWER(@Ten, @Decimal) ,0,1) * 10))
AND 0 = cast((ROUND(@RoundedAmt * POWER(@Ten, @Decimal) ,0,1) -
(ROUND(@RoundedAmt * POWER(@Ten, @Decimal - 1) ,0,1) * 10))
AS INTEGER) % 2
SET @RoundedAmt = ROUND(@RoundedAmt,@Decimal, 1)
ELSE
SET @RoundedAmt = ROUND(@RoundedAmt,@Decimal, 0)
END
RETURN (@RoundedAmt + @WholeAmt)
END
如果要存儲的號碼,財務計算,你應該使用'decimal',定點格式。如果你將數字轉換爲字符串,我會建議'str()'函數。 –
考慮使用Money/Smallmoney,它也有更好的性能。銀行家四捨五入是財務。順便說一下,強制它是微不足道的。 – TomTom
@TomTom我覺得這很平凡 – codingManiac