C#实现T-SQL循环功能

Ped*_*dro 2 c# t-sql rounding

我正在尝试使用截断函数在C#中重现T-SQL Round函数的行为.

这是我试图在C#中重现的SQL行为:

SELECT ROUND(150.757,2,0) -- 150.76
SELECT ROUND(150.757,2,1) -- 150.75

SELECT ROUND(150.747,2,0) -- 150.75
SELECT ROUND(150.747,2,1) -- 150.74
Run Code Online (Sandbox Code Playgroud)

System.Math有,我试图用两种方法.

第一个,只Math.Truncate截断到整个部分,所以它不会帮助我.

另一种方法是Math.Round.

这种方法有两个有趣的重载.

Math.Round(decimal,int)
Math.Round(decimal,int,System.MidpointRounding)
Run Code Online (Sandbox Code Playgroud)

MidpointRounding枚举选项包括:

System.MidpointRounding.AwayFromZero
// When a number is halfway between two others, 
// it is rounded toward the nearest number that is away from zero.

System.MidpointRounding.ToEven
// When a number is halfway between two others,
// it is rounded toward the nearest even number.
Run Code Online (Sandbox Code Playgroud)

Math.Round使用与SQL相同的数据执行两个重载我得到以下结果:

Math.Round(150.757, 2, MidpointRounding.AwayFromZero) // 150.76
Math.Round(150.757, 2, MidpointRounding.ToEven) // 150.76

Math.Round(150.747, 2, MidpointRounding.AwayFromZero) // 150.75
Math.Round(150.747, 2, MidpointRounding.ToEven) // 150.75
Run Code Online (Sandbox Code Playgroud)

鉴于MidpointRounding都没有解决我的问题,在C#中重现T-SQL函数的最佳方法是什么?

更新:

在实现Paul的回答后,我注意到T-SQL ROUND函数有一个奇怪的行为:

SELECT ROUND(150.747,-2,1) // 100
SELECT ROUND(150.747,-2) // 200
Run Code Online (Sandbox Code Playgroud)

我编辑了Paul的答案,包括对这个边缘案例的支持.

Pau*_*sey 5

我想有人会想出一个更好的方法,但这肯定是一种可能的方式!

using System;

static class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(150.757.TruncateWithDecimalPlaces(2));
        Console.WriteLine(150.747.TruncateWithDecimalPlaces(2));
        Console.Read();
    }
    public static double TruncateWithDecimalPlaces(this double input, int decimalPlaces)
    {
        double factor = Math.Pow(10, decimalPlaces);
        return Math.Truncate(input*factor)/factor;
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

150.75
150.74
Run Code Online (Sandbox Code Playgroud)

更完整的实现看起来像这样:

public static double Round(double input, int decimalPlaces, int roundType = 0)
{
    double factor = Math.Pow(10, decimalPlaces);
    if (roundType == 0)
    {
        if (decimalPlaces >= 0)
        {
            return Math.Round(input, decimalPlaces);
        }
        return Math.Round(input * factor) / factor;
    }
    return Math.Truncate(input * factor) / factor;
}
Run Code Online (Sandbox Code Playgroud)