在发布之前,我查看了这两个答案:
C# Finding Nearest Number in Array
Round integer to nearest high number in array
虽然第一个对于其中一个答案中提到的扩展方法有些帮助,但我无法理解它的深度,这将允许我修改和实现它以适应我的特定情况,第二个因为它的数组长度很短,所以不适合我的需要。如果我使用数组存储所有基数为2的数字达到2.68亿,那么它将有相对大量的条目。
基本上我在这里要做的是采用RoundedSpeed(使用Math.Round
将其四舍五入为整数)并将其四舍五入到最接近的数字(它必须永远不会向下舍入,只有向上),这是电源应用于2的结果(示例编号包括16384,32768,65536,131072等)
对于这个特定的例子,我想要舍入的数字是32768.(虽然其他方法可能需要另一个数字,但这对我来说是一个问题,并且超出了本例的范围)。
这是我现在的代码:
double Speed = Math.Pow(2, ((-900 + Time) / -60)) - 1;
double RoundedSpeed = Math.Round(Speed);
最初我正在考虑使用数组来存储相关的数字以进行舍入,但是有没有其他方法可以将RoundedSpeed
舍入到最接近的基数2整数?
答案 0 :(得分:4)
试试这个:
var x = 56;
var y = (int)Math.Pow(2.0, Math.Ceiling(Math.Log(x, 2.0)));
在这种情况下,结果为64。
实际上,这是确定n
2 ^ n = x
的内容,但由于n
可能是一个小数量,因此使用Ceiling
将此数字提升到最接近的整数(或如果已经是整数,请保留它。所以n2 = Ceiling(n)
。然后,它会简单地计算2 ^ n2
以获得y
的结果。
答案 1 :(得分:3)
我会使用循环:
double RoundedSpeed = Math.Round(Speed);
int maxAllowed = 100; // prevent infinite loop
for (int i=1; i < maxAllowed; i++)
{
double number = Math.Pow(2.0, (double)i);
if (number > RoundedSpeed)
return number;
}
如果你不是一个返回某个东西的方法,那么代替返回数字,用数字做一些有用的东西然后添加&#34; break;&#34;停止循环。
您希望添加错误处理以确保不会溢出最大整数值,并且如果您在达到maxAllowed时找不到数字,请执行一些有用的操作。可能有更好的解决方案,但这是一个简单的解决方案。溶液...
答案 2 :(得分:3)
使用按位运算可以非常有效地执行此操作。我在这里使用ulong
作为输入和输出。这将很快运行。
ulong FancyRound(ulong value) {
value -= 1;
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value |= value >> 32;
return value + 1;
}
你可以像这样使用它:
for (ulong i = 1; i < 10; i++) {
Console.WriteLine("{0}: {1}", i, FancyRound(i));
}
输出:
1: 1
2: 2
3: 4
4: 4
5: 8
6: 8
7: 8
8: 8
9: 16
它的工作原理是将所有设置位“级联”,以便在完成所有|
之后,将设置所有低位,直到最高有效位。之后,结果递增以获得2的舍入幂。
答案 3 :(得分:1)
我会这样做,我没有基准测试,所以我不会对速度提出任何要求:
long input = 32111;
long powerTwo = 1;
int count = 0;
int maxCount = 63; //You can't return 2^64 in a long so 63 should be the max here, as we start at 2^0!
while (input > powerTwo && count < maxCount) {
count++;
powerTwo <<= 1;
}
return powerTwo;
输出32,768,因为长(或至少下半部分)在内存中表示为000000001(即1)而<<=
操作只是将位左移1并将结果赋给{ {1}}因此,对于下一次迭代,它变为000000010(这是2),然后它只是在它大于powerTwo
时将它得到的值剔除。
如果您知道它会在溢出之前终止,那么您可以删除计数内容。