【问题标题】:How to round a integer to the close hundred?如何将整数四舍五入到接近百位?
【发布时间】:2022-04-02 13:53:17
【问题描述】:

我不知道我的命名是否正确!无论如何,这些是我拥有的整数,例如:

76
121
9660

我想将它们四舍五入到近百位,例如它们必须成为:

100
100
9700

如何在 C# 中更快地做到这一点?我在想一个算法,但也许 C# 上有一些实用程序?

【问题讨论】:

  • @RoyDictus 他已经尝试过 StackOverflow!
  • @HaLaBi:哈哈哈!是的,我正在尝试关闭@L.B 解决方案(他删除了帖子,不知道:var newi = (int)Math.Round(oldi / 100d)*100;)。我认为这是最好的方法...
  • @markzzz 50 怎么样? 0 还是 100?

标签: c# .net math


【解决方案1】:

试试Math.Round 方法。方法如下:

Math.Round(76d / 100d, 0) * 100;
Math.Round(121d / 100d, 0) * 100;
Math.Round(9660d / 100d, 0) * 100;

【讨论】:

  • 这是最容易理解的解决方案。 +1!你不需要重载来指定0。也许你可以更好地使用中点舍入重载
  • 使用十进制,而不是双精度。
  • 我认为这与大多数人期望的方式不同! Math.Round 将截断该值,因此 Math.Round(50d / 100d, 0) 将为 0。有些人可能期望它为 100。
  • 当您期望 50/100 舍入为 1 时,您可以使用 Math.Round(decimal d, int decimals, MidpointRounding mode) 重载:Math.Round(50d / 100d, 0, MidpointRounding.AwayFromZero);
  • 哦。我刚刚看到@JimAho 为这个问题添加了一个答案,显示了如何使用MidpointRounding 枚举(stackoverflow.com/a/36421665/964821
【解决方案2】:

前段时间我写了一个简单的扩展方法来概括这种舍入:

public static class MathExtensions
{
    public static int Round(this int i, int nearest)
    {
        if (nearest <= 0 || nearest % 10 != 0)
            throw new ArgumentOutOfRangeException("nearest", "Must round to a positive multiple of 10");

        return (i + 5 * nearest / 10) / nearest * nearest;
    }
}

它利用整数除法来找到最接近的舍入。

使用示例:

int example = 152;
Console.WriteLine(example.Round(100)); // round to the nearest 100
Console.WriteLine(example.Round(10)); // round to the nearest 10

在你的例子中:

Console.WriteLine(76.Round(100)); // 100
Console.WriteLine(121.Round(100)); // 100
Console.WriteLine(9660.Round(100)); // 9700

【讨论】:

  • 51.Round(-10) 会得到什么?
  • @L.B 我测试了它,它给了我 40。
  • 它会抛出一个UseYourCommonSense 异常。
  • @JasonLarke 谢谢!另外,它叫什么然后你使用this int i 作为第一个参数。这是我从这个答案中学到的一个新技巧。
  • @GisMofx 它被称为Extension Method 参见msdn.microsoft.com/en-AU/library/bb383977.aspx 他们非常方便。
【解决方案3】:

试试这个表达式:

(n + 50) / 100 * 100

【讨论】:

  • 这是正确答案。这个问题是关于整数的。
【解决方案4】:

只是对@krizzzn 接受的答案的一些补充......

请注意以下将返回 0:

Math.Round(50d / 100d, 0) * 100;

考虑使用以下内容并使其返回 100:

Math.Round(50d / 100d, 0, MidpointRounding.AwayFromZero) * 100;

根据您的操作,使用小数可能是更好的选择(注意 m):

Math.Round(50m / 100m, 0, MidpointRounding.AwayFromZero) * 100m;

【讨论】:

    【解决方案5】:

    我知道这是一个旧线程。我写了一个新方法。希望这对某些人有用。

            public static double Round(this float value, int precision)
            {
                if (precision < -4 && precision > 15)
                    throw new ArgumentOutOfRangeException("precision", "Must be and integer between -4 and 15");
    
                if (precision >= 0) return Math.Round(value, precision);
                else
                {
                    precision = (int)Math.Pow(10, Math.Abs(precision));
                    value = value + (5 * precision / 10);
                    return Math.Round(value - (value % precision), 0);
                }
            }
    

    例子:

        float value = 6666.677777F;
        Console.Write(value.Round(2)); //6666.68
        Console.Write(value.Round(0)); //6667
        Console.Write(value.Round(-2)); //6700 
    

    【讨论】:

      【解决方案6】:

      你好,我写了这个扩展,你传递的每个数字都会得到下一个 100

      /// <summary>
          /// this extension gets the next hunfìdred for any number you whant
          /// </summary>
          /// <param name="i">numeber to rounded</param>
          /// <returns>the next hundred number</returns>
          /// <remarks>
          /// eg.:
          /// i =   21 gets 100
          /// i =  121 gets 200
          /// i =  200 gets 300
          /// i = 1211 gets 1300
          /// i = -108 gets -200
          /// </remarks>
          public static int RoundToNextHundred(this int i)
          {
              return i += (100 * Math.Sign(i) - i % 100);
              //use this line below if you want RoundHundred not NEXT
              //return i % 100 == byte.MinValue? i : i += (100 * Math.Sign(i) - i % 100);
          }
      
          //and for answer at title point use this algoritm
          var closeHundred = Math.Round(number / 100D)*100;
      
          //and here the extension method if you prefer
      
          /// <summary>
          /// this extension gets the close hundred for any number you whant
          /// </summary>
          /// <param name="number">number to be rounded</param>
          /// <returns>the close hundred number</returns>
          /// <remarks>
          /// eg.:
          /// number =   21 gets    0
          /// number =  149 gets  100
          /// number =  151 gets  200
          /// number = -149 gets -100
          /// number = -151 gets -200
          /// </remarks>
          public static int RoundCloseHundred(this int number)
          {
              return (int)Math.Round(number / 100D) * 100;
          }
      

      【讨论】:

      • 这个算法实际上并没有四舍五入,而是搜索value % 100 == 0的下一个值,例如当使用 i = 200 调用此方法时,它返回 300。
      • 而且它不适用于负值:当使用 i = -4 调用此方法时,它返回 100,尽管我希望为 0。
      • 这不是四舍五入的工作方式 - 当我已经有了 200 的值时,它不应该四舍五入到 300(因为 200 已经是舍入比例的量化值)。如果您进行正常整数舍入,那么您也不会期望以下语句为真:Math.Round(1) == 2
      • 我插入负数,现在如果你插入负数,这将得到下一个负百
      • 请记住该方法称为 Round NEXT Hundred 而不是 RoundHundred。第二种方式你是对的,但 300 是 200 的下一百个
      【解决方案7】:

      如果您只想将整数向上取整(就像 OP 实际所做的那样),那么您可以采用以下解决方案:

      public static class MathExtensions
      {
          public static int RoundUpTo(this int number, int nearest)
          {
              if (nearest < 10 || nearest % 10 != 0)
                  throw new ArgumentOutOfRangeException(nameof(nearest), $"{nameof(nearest)} must be a positive multiple of 10, but you specified {nearest}.");
      
              int modulo = number % nearest;
              return modulo == 0 ? number : modulo > 0 ? number + (nearest - modulo) : number - modulo;
          }
      }
      

      如果您想执行浮点(或十进制)舍入,请求助于@krizzzn 和@Jim Aho 的答案。

      【讨论】:

        【解决方案8】:
        int num = 9660;
        int remainder = num % 100;
        Console.WriteLine(remainder < 50 ? num - remainder : num + (100 -remainder));
        

        注意:我还没有彻底测试过。

        【讨论】:

          【解决方案9】:

          我在内部有一个类似的项目,业务需求是在给定数字的 100 范围内搜索并找到重复的数据库记录。因此,如果用户使用第 856 行,我将搜索 800 - 899。如果用户使用 8567,我将搜索 8500 - 8599。不是精确到 100 的四舍五入,但我认为我会将我的独特方法作为其中一些基本编码问题嵌入在更大的业务项目中。为了测试这一点,我从 1 到 99999 播种了一个十进制列表,并将结果输出到一个文件中。

              /// <summary>
              /// This method accepts an inbound Line Number and returns the line range
              /// in the form of lowest to highest based on 100's
              /// Example would be 9122 returns 9100 - 9199
              /// It's used for generating some additional BOM Temp functionality.
              /// </summary>
              /// <param name="inboundNumber"></param>
              /// <returns></returns>
              public static ProjectLineRange CalculateLineRange(decimal inboundNumber)
              {
                  var lineRange = new ProjectLineRange();
                  var numberLength = inboundNumber.ToString(CultureInfo.InvariantCulture).Length;
          
                  switch (numberLength)
                  {
                      case 0: //NULL?
                          break;
                      case 1: //Represents 1 - 9
                          lineRange.LineBottom = 1;
                          lineRange.LineTop = 99;
                          break;
                      case 2: //Represents 10 - 99
                          lineRange.LineBottom = 1;
                          lineRange.LineTop = 99;
                          break;
                      case 3: //Represents 100 - 999
                          lineRange = CalculateHundredsRange((int)(inboundNumber / 100));
                          break;
                      case 4: //Represents 1000 - 9999
                          lineRange = CalculateThousandsRange(
                              Convert.ToInt32(inboundNumber.ToString(CultureInfo.InvariantCulture).Substring(1, 1)),
                              Convert.ToInt32(inboundNumber.ToString(CultureInfo.InvariantCulture).Substring(0, 1)));
                          break;
                      case 5: //Represents 10000 - 99999
                          lineRange = CalculateTenThousandsRange(
                              Convert.ToInt32(inboundNumber.ToString(CultureInfo.InvariantCulture).Substring(2, 1)),
                              Convert.ToInt32(inboundNumber.ToString(CultureInfo.InvariantCulture).Substring(1, 1)),
                              Convert.ToInt32(inboundNumber.ToString(CultureInfo.InvariantCulture).Substring(0, 1)));
                          break;
                  }
          
                  return lineRange;
              }
          
          public class ProjectLineRange
              {
                 public decimal LineBottom { get; set; }
                 public decimal LineTop { get; set; }
              }
          
              /// <summary>
              /// Helper method to return the range for the 100's place
              /// </summary>
              /// <param name="hundredsPlaceValue"></param>
              /// <returns></returns>
              public static ProjectLineRange CalculateHundredsRange(int hundredsPlaceValue)
              {
                  var tempLineRange = new ProjectLineRange();
                  tempLineRange.LineBottom = hundredsPlaceValue * 100;
                  tempLineRange.LineTop = tempLineRange.LineBottom + 99;
          
                  return tempLineRange;
              }
          
              /// <summary>
              /// Helper method to return the range for the 100's place when factoring a 1000's number
              /// </summary>
              /// <param name="hundredsPlaceValue"></param>
              /// <param name="thousandsPlaceValue"></param>
              /// <returns></returns>
              public static ProjectLineRange CalculateThousandsRange(int hundredsPlaceValue, int thousandsPlaceValue)
              {
                  var tempLineRange = new ProjectLineRange();
                  var tempThousands = thousandsPlaceValue * 1000;
                  var hundredsRange = CalculateHundredsRange(hundredsPlaceValue);
                  tempLineRange.LineBottom = tempThousands + hundredsRange.LineBottom;
                  tempLineRange.LineTop = tempThousands + hundredsRange.LineTop;
          
                  return tempLineRange;
              }
          
              /// <summary>
              /// Helper method to return the range for the 100's place when factoring a 10000's number
              /// </summary>
              /// <param name="hundredsPlaceValue"></param>
              /// <param name="thousandsPlaceValue"></param>
              /// <param name="tenThousandsPlaceValue"></param>
              /// <returns></returns>
              public static ProjectLineRange CalculateTenThousandsRange(int hundredsPlaceValue, int thousandsPlaceValue, int tenThousandsPlaceValue)
              {
                  var tempLineRange = new ProjectLineRange();
                  var tempThousands = thousandsPlaceValue * 1000;
                  var tempTenThousands = tenThousandsPlaceValue * 10000;
                  var hundredsRange = CalculateHundredsRange(hundredsPlaceValue);
                  tempLineRange.LineBottom = tempTenThousands + tempThousands + hundredsRange.LineBottom;
                  tempLineRange.LineTop = tempTenThousands + tempThousands + hundredsRange.LineTop;
          
                  return tempLineRange;
              }
          

          【讨论】:

            【解决方案10】:
            public static class Maths
            {
                public static int Round(this int value, int precision)
                {
                    var coef = Math.Pow(10, Math.Abs(precision));
                    var x = (int)Math.Round(value / coef, 0);
                    return x * (int)coef;
                }
            }
            

            变量编号 = 34569;

            Debug.WriteLine(number.Round(0));//34569

            Debug.WriteLine(number.Round(1));//34570

            Debug.WriteLine(number.Round(2));//34600

            Debug.WriteLine(number.Round(3));//35000

            Debug.WriteLine(number.Round(4));//30000

            Debug.WriteLine(number.Round(5));// 0

            Debug.WriteLine(number.Round(6));// 0

            【讨论】:

              猜你喜欢
              • 2021-10-31
              • 1970-01-01
              • 1970-01-01
              • 2011-03-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多