如何将C#值四舍五入到最接近的整数?


78

我想四舍五入为整数。

例如,

double a=0.4, b=0.5;

我想将它们都更改为整数。

以便

int aa=0, bb=1;

aa来自abb来自b

有什么公式可以做到吗?


5
如果双精度数超出int范围,您想怎么办?
埃里克·利珀特

Answers:


204

使用Math.Ceiling围捕

Math.Ceiling(0.5); // 1

用于Math.Round四舍五入

Math.Round(0.5, MidpointRounding.AwayFromZero); // 1

Math.Floor舍入

Math.Floor(0.5); // 0

您需要使用Math.Round做更多的工作。它提供了一个枚举(MidpointRounding)以准确指定行为。
jnielsen

@jnielsen:感谢您指出这一点并提供了代码示例。我已经改正了。
BrunoLM

最简单有效的方法是Math.Ceiling
yopez83 '18

请注意,Math.Ceiling如果该数字已经完整,则将返回相同的数字,它将不会四舍五入
大笔钱


5

.NET框架Math.Round默认使用银行家的四舍五入。您应该使用此重载:

Math.Round(0.5d, MidpointRounding.AwayFromZero)  //1
Math.Round(0.4d, MidpointRounding.AwayFromZero)  //0

3

使用函数代替MidpointRounding.AwayFromZero

myRound(1.11125,4)

答案:-1.1114

public static Double myRound(Double Value, int places = 1000)
{
    Double myvalue = (Double)Value;
    if (places == 1000)
    {
        if (myvalue - (int)myvalue == 0.5)
        {
            myvalue = myvalue + 0.1;
            return (Double)Math.Round(myvalue);
        }
        return (Double)Math.Round(myvalue);
        places = myvalue.ToString().Substring(myvalue.ToString().IndexOf(".") + 1).Length - 1;
    } if ((myvalue * Math.Pow(10, places)) - (int)(myvalue * Math.Pow(10, places)) > 0.49)
    {
        myvalue = (myvalue * Math.Pow(10, places + 1)) + 1;
        myvalue = (myvalue / Math.Pow(10, places + 1));
    }
    return (Double)Math.Round(myvalue, places);
}

2
如果当前区域性使用逗号而不是句点的小数点,则此操作将失败。
肖恩·里德

3

圆形数学

将双精度浮点值四舍五入到最接近的整数值。


但是:“此方法的行为遵循IEEE标准754,第4节。这种舍入有时也称为舍入到最接近的舍入或银行的舍入。……”

0

由于浮点舍入错误,Math.Round(0.5)返回零,因此您需要向原始值添加一个舍入误差量以确保它不会舍入,例如。

Console.WriteLine(Math.Round(0.5, 0).ToString()); // outputs 0 (!!)
Console.WriteLine(Math.Round(1.5, 0).ToString()); // outputs 2
Console.WriteLine(Math.Round(0.5 + 0.00000001, 0).ToString()); // outputs 1
Console.WriteLine(Math.Round(1.5 + 0.00000001, 0).ToString()); // outputs 2
Console.ReadKey();

对我来说没关系。.我也发现了这一点。
威廉

8
没有错 1/2可以精确地表示为双精度。文档说:“如果a的小数部分位于两个整数之间的中间,其中一个是偶数而另一个是奇数,则返回偶数。” 0是偶数。这个软糖因素将使像0.499999995这样的数字四舍五入。
马修·弗拉申

为单挑加油打气。我试图确保OP知道Round不能像其他人所建议的那样简单地工作。幸运的是,OP现在知道要当心,而且我对Round本身有了更好的了解。=)

0

也可以舍入负整数

// performing d = c * 3/4 where d can be pos or neg
d = ((c * a) + ((c>0? (b>>1):-(b>>1)))) / b;
// explanation:
// 1.) multiply:          c * a  
// 2.) if c is negative:  (c>0? subtract half of the dividend 
//                              (b>>1) is bit shift right = (b/2)
//     if c is positive:  else  add half of the dividend 
// 3.) do the division
// on a C51/52 (8bit embedded) or similar like ATmega the below code may execute in approx 12cpu cycles (not tested)

从这里的其他地方的尖端延伸。抱歉,从哪里错过了。

/* Example test: integer rounding example including negative*/
#include <stdio.h>
#include <string.h>

int main () {
   //rounding negative int
   // doing something like d = c * 3/4
   int a=3;
   int b=4;
   int c=-5;
   int d;
   int s=c;
   int e=c+10;


   for(int f=s; f<=e; f++) {
      printf("%d\t",f);

      double cd=f, ad=a, bd=b , dd;

      // d = c * 3/4  with double
      dd = cd * ad / bd;

      printf("%.2f\t",dd);
      printf("%.1f\t",dd);        
      printf("%.0f\t",dd);

      // try again with typecast have used that a lot in Borland C++ 35 years ago....... maybe evolution has overtaken it ;) ***
      // doing div before mul on purpose
      dd =(double)c * ((double)a / (double)b);
      printf("%.2f\t",dd);

      c=f;
      // d = c * 3/4  with integer rounding
      d = ((c * a) + ((c>0? (b>>1):-(b>>1)))) / b;
      printf("%d\t",d);
      puts("");
  }
 return 0;
}

/* test output
in  2f     1f   0f cast int   
-5  -3.75   -3.8    -4  -3.75   -4  
-4  -3.00   -3.0    -3  -3.75   -3  
-3  -2.25   -2.2    -2  -3.00   -2  
-2  -1.50   -1.5    -2  -2.25   -2  
-1  -0.75   -0.8    -1  -1.50   -1  
 0   0.00    0.0     0  -0.75    0  
 1   0.75    0.8     1   0.00    1  
 2   1.50    1.5     2   0.75    2  
 3   2.25    2.2     2   1.50    2  
 4   3.00    3.0     3   2.25  3    
 5   3.75    3.8     4   3.00   

// by the way evolution: 
// Is there any decent small integer library out there for that by now?

-2

很简单。因此,请遵循以下代码。

decimal d = 10.5;
int roundNumber = (int)Math.Floor(d + 0.5);

结果是11


为什么Math.Floor要在OP要舍入到最接近的位置时使用?这对于负值将不起作用
phuclv

本示例仅适用于正值。
TechnicalKalsa

您甚至没有在问题中提到这一点。OP并没有说他只对正整数感兴趣。无论如何,这是没有用的,因为已经有Math.Round
phuclv

-2

另外一个选项:

string strVal = "32.11"; // will return 33
// string strVal = "32.00" // returns 32
// string strVal = "32.98" // returns 33

string[] valStr = strVal.Split('.');

int32 leftSide = Convert.ToInt32(valStr[0]);
int32 rightSide = Convert.ToInt32(valStr[1]);

if (rightSide > 0)
    leftSide = leftSide + 1;


return (leftSide);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.