我尝试通过以下方式将二进制数组转换为十进制数组:
uint8_t array[8] = {1,1,1,1,0,1,1,1} ;
int decimal = 0 ;
for(int i = 0 ; i < 8 ; i++)
decimal = (decimal << 1) + array[i] ;实际上,我必须将64位二进制数组转换为十进制数组,并且我必须这样做数百万次。
有没有人能帮我,有没有更快的方法来做上面的事情?或者是上面的那个很好?
发布于 2013-02-06 16:39:08
你的方法是足够的,我不会把位运算和转换成十进制的“数学”方式混在一起,也就是使用其中的一种。
decimal = decimal << 1 | array[i];或
decimal = decimal * 2 + array[i];发布于 2013-02-06 17:51:18
在尝试任何优化之前,分析代码是很重要的。对它进行计时,查看生成的代码,只有当您了解正在发生的事情时才进行优化。
正如已经指出的,最好的优化是不做某事,而是进行更高层次的更改,以消除需要。
然而..。
你可能想要在这里做的大多数更改,很可能是编译器已经做过的事情(对编译器来说,移位等同于乘法)。一些方法实际上可能会阻止编译器进行优化(将add更改为or会限制编译器-有更多的方法可以添加数字,只有您知道在这种情况下结果是相同的)。
指针算术可能更好,但编译器并不愚蠢-它应该已经生成了用于解引用数组的像样的代码,所以你需要检查一下,你实际上没有通过引入一个额外的变量而使事情变得更糟。
在这种情况下,循环计数是定义良好且有限的,因此展开可能是有意义的。
此外,它还取决于您希望结果在多大程度上依赖于目标架构。如果你想要可移植性,这很难(呃)优化。
例如,下面的代码在这里会产生更好的代码:
unsigned int x0 = *(unsigned int *)array;
unsigned int x1 = *(unsigned int *)(array+4);
int decimal = ((x0 * 0x8040201) >> 20) + ((x1 * 0x8040201) >> 24);我可能还会推出一个64位版本,一次8位而不是4位。
但它绝对不是可移植的代码。如果我知道我运行的是什么,并且我只想快速处理数字,我可能会在本地使用它。但我可能不会把它放在生产代码中。当然,如果没有记录它做了什么,并且没有随附的单元测试来检查它是否真正工作,那么肯定不会。
发布于 2013-02-06 17:51:52
您可以使用accumulate,并使用双倍和加法二进制操作:
int doubleSumAndAdd(const int& sum, const int& next) {
return (sum * 2) + next;
}
int decimal = accumulate(array, array+ARRAY_SIZE,
doubleSumAndAdd);这会产生大端整数,而操作码会产生小端整数。
https://stackoverflow.com/questions/14724627
复制相似问题