Wij*_*tha 4 sql sql-server sql-server-2008
据我所知,当四舍五入为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)
Run Code Online (Sandbox Code Playgroud)
如果我们做所有的总结,
2.435 + 2.445 = 4.88
2.44 + 2.44 = 4.88
Run Code Online (Sandbox Code Playgroud)
我很确定在.Net中也可以进行这种四舍五入。
但是在SQL Server中,总会四舍五入,这在数学上是不正确的。
SELECT round(2.345, 2) = 2.35
SELECT round(2.335, 2) => 2.34
Run Code Online (Sandbox Code Playgroud)
这导致四舍五入后的总值相差1美分。
2.345 + 2.335 = 4.68
2.35 + 2.34 = 4.69 => which is not correct
Run Code Online (Sandbox Code Playgroud)
我已经尝试过使用十进制和货币数据类型。
难道我做错了什么?有没有解决的办法?
如果您确实想在 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
Run Code Online (Sandbox Code Playgroud)
在数学上四舍五入是正确的,也是基础数学中最常用的四舍五入类型。其他类型的四舍五入也是有效的,但不是基础数学,但由于 0.5 通常是一个争议数,因此更常用于某些领域。
您在数学上所说的舍入实际上是银行家舍入,这是金融业务中使用的舍入类型。
您正在寻找Banker的舍入 -这是C#中的默认舍入,但不是SQL Server ROUND()的工作方式。
请参见为什么Sql Server 2000上的TSQL会舍入小数位数不一致?以及http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/sql-server-rounding-methods和http://www.chrispoulter.com/blog/post/rounding-decimals-using-net -和-t-sql