Math 如何将奇数整数四舍五入到二的最近幂
奇数整数加一或减一,使偶数结果更接近二的最近幂Math 如何将奇数整数四舍五入到二的最近幂,math,bit-manipulation,rounding,Math,Bit Manipulation,Rounding,奇数整数加一或减一,使偶数结果更接近二的最近幂 if ( ??? ) x += 1; else x -= 1;// x > 2 and odd 例如,25到47向32进位,25到31加一,33到47减一。23轮向下,16比22,49轮向上,64比50 有没有一种方法可以做到这一点,而不需要找到两个四舍五入的特定幂。我知道如何使用对数或计数位来获得2的特定幂 if ( ??? ) x += 1; else x -= 1;// x > 2 and odd 我的具体使用案例是将奇数大小
if ( ??? ) x += 1; else x -= 1;// x > 2 and odd
例如,25到47向32进位,25到31加一,33到47减一。23轮向下,16比22,49轮向上,64比50
有没有一种方法可以做到这一点,而不需要找到两个四舍五入的特定幂。我知道如何使用对数或计数位来获得2的特定幂
if ( ??? ) x += 1; else x -= 1;// x > 2 and odd
我的具体使用案例是将奇数大小的输入拆分为karatsuba乘法。对于一个32位整数(只有32个条目)保持2的所有幂并没有什么大不了的。对它应该位于的位置进行快速二进制搜索。然后你可以很容易地找出哪个数字更接近从高和低的数字减去,并得到abs。然后,您可以轻松决定添加哪一个 您可以通过获取数字的日志基数2并使用它索引到数组中来避免搜索 更新:提醒:此代码未经过彻底测试
#include <array>
#include <cmath>
#include <iostream>
const std::array<unsigned int,32> powers =
{
1,1<<1,1<<2,1<<3,1<<4,1<<5,1<<6,1<<7,1<<8,1<<9,1<<10,1<<11,1<<12,1<<13,1<<14,
1<<15,1<<16,1<<17,1<18,1<<19,1<<20,1<<21,1<<22,1<<23,1<<24,1<<25,1<<26,1<<27,
1<<28,1<<29,1<<30,1<<31 -1
};
std::array<unsigned int,32> powers_of_two() {
std::array<unsigned int,32> powers_of_two{};
for (unsigned int i = 0; i < 31; ++i) {
powers_of_two[i] = 1 << i;
}
powers_of_two[31]=~0;
return powers_of_two;
}
unsigned int round_to_closest(unsigned int number) {
if (number % 2 == 0) return number;
unsigned int i = std::ceil(std::log2(number));
//higher index
return (powers[i]-number) < (number - powers[i-1]) ?
++number:--number;
}
int main() {
std::cout << round_to_closest(27) << std::endl;
std::cout << round_to_closest(23) << std::endl;
return 0;
}
#包括
#包括
#包括
常数std::数组幂=
{
1,1对于一个32位整数(只有32个条目),保留2的所有幂并不是什么大问题。对它应该位于的位置进行快速的二进制搜索。然后,通过从较高和较低的数字中减去并获得abs,您可以轻松地确定它更接近哪个数字。然后,您可以轻松地决定添加到哪个数字
您可以通过获取数字的日志基数2并使用它索引到数组中来避免搜索
更新:提醒:此代码未经过彻底测试
#include <array>
#include <cmath>
#include <iostream>
const std::array<unsigned int,32> powers =
{
1,1<<1,1<<2,1<<3,1<<4,1<<5,1<<6,1<<7,1<<8,1<<9,1<<10,1<<11,1<<12,1<<13,1<<14,
1<<15,1<<16,1<<17,1<18,1<<19,1<<20,1<<21,1<<22,1<<23,1<<24,1<<25,1<<26,1<<27,
1<<28,1<<29,1<<30,1<<31 -1
};
std::array<unsigned int,32> powers_of_two() {
std::array<unsigned int,32> powers_of_two{};
for (unsigned int i = 0; i < 31; ++i) {
powers_of_two[i] = 1 << i;
}
powers_of_two[31]=~0;
return powers_of_two;
}
unsigned int round_to_closest(unsigned int number) {
if (number % 2 == 0) return number;
unsigned int i = std::ceil(std::log2(number));
//higher index
return (powers[i]-number) < (number - powers[i-1]) ?
++number:--number;
}
int main() {
std::cout << round_to_closest(27) << std::endl;
std::cout << round_to_closest(23) << std::endl;
return 0;
}
#包括
#包括
#包括
常数std::数组幂=
{
1,1正如@aaronman所指出的,如果处理整数,唯一最快的方法就是在表中有2的所有幂,因为没有那么多。通过构造,在无符号32位整数中有32个2的幂(包括数字1),在64位整数中有64个,依此类推
但是,如果你想在一般情况下即时计算,你可以很容易地计算任意数的2的周围幂
#include <math.h>
(...)
double bottom, top, number, exponent;
number = 1234; // Set the value for number
exponent = int(log(number) / log(2.0)); // int(10.2691) = 10
bottom = pow(2, exponent); // 2^10 = 1024
top = bottom * 2; // 2048
// Calculate the difference between number, top and bottom and add or subtract
// 1 accordingly
number = (top - number) < (number - bottom) ? number + 1 : number - 1;
#包括
(...)
双底、上、数、指数;
number=1234;//设置number的值
指数=int(log(number)/log(2.0));//int(10.2691)=10
底部=功率(2,指数);//2^10=1024
顶部=底部*2;//2048
//计算数字、顶部和底部之间的差值,然后进行加减运算
//1相应地
数字=(顶部-数字)<(底部-数字)?数字+1:数字-1;
正如@aaronman所指出的,如果处理整数,唯一最快的方法是在表中有2的所有幂,因为没有那么多。通过构造,在无符号32位整数中有32个2的幂(包括数字1),在64位整数中有64个,依此类推
但是,如果你想在一般情况下即时计算,你可以很容易地计算任意数的2的周围幂
#include <math.h>
(...)
double bottom, top, number, exponent;
number = 1234; // Set the value for number
exponent = int(log(number) / log(2.0)); // int(10.2691) = 10
bottom = pow(2, exponent); // 2^10 = 1024
top = bottom * 2; // 2048
// Calculate the difference between number, top and bottom and add or subtract
// 1 accordingly
number = (top - number) < (number - bottom) ? number + 1 : number - 1;
#包括
(...)
双底、上、数、指数;
number=1234;//设置number的值
指数=int(log(number)/log(2.0));//int(10.2691)=10
底部=功率(2,指数);//2^10=1024
顶部=底部*2;//2048
//计算数字、顶部和底部之间的差值,然后进行加减运算
//1相应地
数字=(顶部-数字)<(底部-数字)?数字+1:数字-1;
如果设置了第二个最高有效位,则添加,否则减去
如果((x&(x>>1))>(x>>2))x+=1;否则x-=1;如果设置了第二个最高有效位,则进行加法,否则进行减法
如果((x&(x>>1))>(x>>2))x+=1;否则x-=1;表示最近的(不是最大的或相等的)-请参见:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
unsigned int val = atoi(argv[1]);
unsigned int x = val;
unsigned int result;
do {
result = x;
} while(x &= x - 1);
if((result >> 1) & val)
result <<= 1;
printf("result=%u\n", result);
return 0;
}
到
有关最近的(不是最大的或相等的)-请参见:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
unsigned int val = atoi(argv[1]);
unsigned int x = val;
unsigned int result;
do {
result = x;
} while(x &= x - 1);
if((result >> 1) & val)
result <<= 1;
printf("result=%u\n", result);
return 0;
}
到
因此,对于我的用例,即使整数也不改变。检查我的代码,它包含日志索引的解决方案,我将使第一个函数成为constexpr,但您得到了要点,所以对于我的用例,即使整数也不改变。检查我的代码,它包含日志索引的解决方案之一,我将使第一个函数成为一个constexpr,但你得到了点好吧,我想这实际上是非常聪明的;)谢谢。在我最终找到它之前,我有一些错误的开始。我认为在编译时创建一个向量在技术上可能会更快,只是说你可以使用你的技巧生成计算向量OK我想这其实很聪明;)谢谢。在我最终弄明白之前,我有过一些错误的开始。我认为在编译时创建向量在技术上可能会更快,只是说你可以使用你的技巧来生成向量