据我所知,当四舍五入为5时,四舍五入应按以下方式进行。
2.435 => 2.44 (Round Up, if rounding to digit(3) is odd number) 2.445 => 2.44 (Round Down, if rounding to digit(4) is even number)
如果我们做所有的总结,
2.435 + 2.445 = 4.88 2.44 + 2.44 = 4.88
我很确定在.Net中也可以进行这种四舍五入。
但是在SQL Server中,总会四舍五入,这在数学上是不正确的。
SELECT round(2.345, 2) = 2.35 SELECT round(2.335, 2) => 2.34
这导致四舍五入后的总值相差1美分。
2.345 + 2.335 = 4.68 2.35 + 2.34 = 4.69 => which is not correct
我已经尝试过使用十进制和货币数据类型。
难道我做错了什么?有没有解决的办法?
如果您确实想在SQL Server中使用银行取整…
CREATE FUNCTION BankersRounding(@value decimal(36,11), @significantDigits INT) RETURNS MONEY AS BEGIN -- if value = 12.345 and signficantDigits = 2... -- base = 1000 declare @base int = power(10, @significantDigits + 1) -- roundingValue = 12345 declare @roundingValue decimal(36,11) = floor(abs(@value) * @base) -- roundingDigit = 5 declare @roundingDigit int = @roundingValue % 10 -- significantValue = 1234 declare @significantValue decimal(36,11) = floor(@roundingValue / 10) -- lastSignificantDigit = 4 declare @lastSignificantDigit int = @significantValue % 10 -- awayFromZero = 12.35 declare @awayFromZero money = (@significantValue + 1) / (@base / 10) -- towardsZero = 12.34 declare @towardsZero money = @significantValue / (@base / 10) -- negative values handled slightly different if @value < 0 begin -- awayFromZero = -12.35 set @awayFromZero = ((-1 * @significantValue) - 1) / (@base / 10) -- towardsZero = -12.34 set @towardsZero = (-1 * @significantValue) / (@base / 10) end -- default to towards zero (i.e. assume thousandths digit is 0-4) declare @rv money = @towardsZero if @roundingDigit > 5 set @rv = @awayFromZero -- 5-9 goes away from 0 else if @roundingDigit = 5 begin -- 5 goes to nearest even number (towards zero if even, away from zero if odd) set @rv = case when @lastSignificantDigit % 2 = 0 then @towardsZero else @awayFromZero end end return @rv end