我需要一个函数,通过该函数我可以将数字转换为给定倍数的最接近值。
我想要一个数字数组设置为16的neareast倍数,所以2 = 0,5 = 0,11 = 16,17 = 16,30 = 32等
感谢
答案 0 :(得分:27)
为此,您需要进行一些划分和舍入:
int value = 30;
int factor = 16;
int nearestMultiple =
(int)Math.Round(
(value / (double)factor),
MidpointRounding.AwayFromZero
) * factor;
小心使用这种技术。 Math.Round(double)
超载认为邪恶的突变MidpointRounding.ToEven
是最好的默认行为,即使我们在学校之前学到的是CLR所称的MidpointRounding.AwayFromZero
。例如:
var x = Math.Round(1.5); // x is 2.0, like you'd expect
x = Math.Round(0.5); // x is 0. WAT?!
答案 1 :(得分:6)
16*((n+8)/16)
是你想要的公式,特别是你想要将8转换为16(它同样接近0到16,所以不可能根据“最近的”来决定如何转换它。多个“概念,你必须决定! - ),当然一直是24到32,40到48,等等。如果您希望将8转换为0而不是16(而且始终为24到16,依此类推),请使用+7
代替+8
。
要使用通用X
代替硬编码16
,则公式为X*((n+X/2)/X)
(如果X
为偶数,则与上一段中的条件相同)。
编辑:不需要像其他答案所暗示的那样搞乱浮点数,但你做需要乘以X
(我有错误地省略了。)
答案 2 :(得分:6)
您不需要进行任何浮点除法,这是不必要的。使用余数运算符:
int rem = value % multiple;
int result = value - rem;
if (rem > (multiple / 2))
result += multiple;
答案 3 :(得分:2)
将中间向+∞
int RoundNearest16(int value)
{
return (value + 8) & ~0xF;
}
答案 4 :(得分:0)
如果倍数小于1,情况会有点复杂。我写了这个通用函数:
public float NearestRound(float x, float delX)
{
if (delX < 1)
{
float i = (float)Math.Floor(x);
float x2 = i;
while ((x2 += delX) < x) ;
float x1 = x2 - delX;
return (Math.Abs(x - x1) < Math.Abs(x - x2)) ? x1 : x2;
}
else {
return (float)Math.Round(x / delX, MidpointRounding.AwayFromZero) * delX;
}
}
/* Sample:
x: 101 multiple:2 NearestRound -> 102
x: 107 multiple:2 NearestRound -> 108
x: 100.9 multiple:2 NearestRound -> 100
x: 1 multiple:0.25 NearestRound -> 1
x: 1.35 multiple:0.25 NearestRound -> 1.25
x: 1.77 multiple:0.25 NearestRound -> 1.75
x: 1.9 multiple:0.25 NearestRound -> 2 */
答案 5 :(得分:0)
如果舍入到最接近的浮点数倍,可以使用:
public static float convert(float value, float multipleOf)
{
return (float) Math.Round((decimal)value / (decimal)multipleOf, MidpointRounding.AwayFromZero) * multipleOf;
}
然后你可以使用这样的功能:
Console.WriteLine("Convert 10.723: " + convert(10.723f, 0.5f)); // 10.5