在C#中舍入double值

Ste*_*eve 30 c# double rounding

我想在C#中对double值进行舍入方法.它需要能够将double值舍入到任何舍入精度值.我手边的代码看起来像:

public static double RoundI(double number, double roundingInterval) {

    if (roundingInterval == 0.0)
    {
        return;
    }

    double intv = Math.Abs(roundingInterval);
    double sign = Math.Sign(number);
    double val = Math.Abs(number);

    double valIntvRatio = val / intv;
    double k = Math.Floor(valIntvRatio);
    double m = valIntvRatio - k;

    bool mGreaterThanMidPoint = ((m - 0.5) >= 1e-14) ? true : false;
    bool mInMidpoint = (Math.Abs(m - 0.5) < 1e-14) ? true : false;
    return (mGreaterThanMidPoint || mInMidpoint) ? sign * ((k + 1) * intv) : sign * (k * intv);
}
Run Code Online (Sandbox Code Playgroud)

所以RoundI(100,3)应该给出99而RoundI(1.2345,0.001)应该给出1.235.

问题是,RoundI(1.275,0.01)返回1.27,而不是1.28.这是因为当执行双valIntvRatio = val/intv,即double valIntvRatio = 1.275/0.01时,它给出0.12749999999999.我知道这是任何编程语言中双重表示的问题.我的问题是,有没有一个标准的代码来做这样的事情,而不需要担心双精度?在这里我将容忍度设置为1e-14,但这对于这个问题来说太限制了,我不知道要设置的正确容差是多少.感谢您的任何帮助.

Jim*_*mmy 43

decimal正如Kibbee指出的那样使用的例子

double d = 1.275;
Math.Round(d, 2);          // 1.27
Math.Round((decimal)d, 2); // 1.28 
Run Code Online (Sandbox Code Playgroud)

  • @Zefnus因为它使用了Banker的舍入.如果你想要它舍入到0.01,使用`Math.Round((十进制)d,2,MidpointRounding.AwayFromZero) (8认同)

Ace*_*ark 5

double d = 1.2345;

Math.Round(d, 2);
Run Code Online (Sandbox Code Playgroud)

上面的代码应该可以解决问题.