我不知道我的命名是否正确!无论如何,这些是我拥有的整数,例如:
76
121
9660
而且我想将它们四舍五入到接近一百,例如它们必须变成:
100
100
9700
如何在 C# 中更快地做到这一点?我考虑了一种算法,但也许 C# 上有一些实用程序?
试试Math.Round
方法。就是这样:
Math.Round(76d / 100d, 0) * 100;
Math.Round(121d / 100d, 0) * 100;
Math.Round(9660d / 100d, 0) * 100;
不久前我写了一个简单的扩展方法来概括这种舍入:
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
试试这个表达式:
(n + 50) / 100 * 100
只是对@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;
我知道这是一个旧线程。我写了一个新方法。希望这对某些人有用。
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
嗨,我写了这个扩展名,你传递的每个数字都会得到下一个百
/// <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;
}
如果您只想将整数向上取整(就像 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 的答案。
int num = 9660;
int remainder = num % 100;
Console.WriteLine(remainder < 50 ? num - remainder : num + (100 -remainder));
注意:我还没有彻底测试过。
我在内部有一个类似的项目,业务需求是在给定数字的 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;
}