【发布时间】:2012-11-22 15:18:30
【问题描述】:
给定一个len 类型的signed short 元素数组,它是在数组中的最大绝对值元素中找到最高有效位集的位置。例如,如果数组 L 包含 {-134, 123, 0, -890},那么 f(L) 应该返回 floor(log2(abs(-890)))+1。
这是我目前的功能:
short MSBSetMaxMagnitude(const short *p, int len)
{
unsigned int t = 0;
while (len > 0)
{
t |= abs(*p);
p++;
len--;
}
if(t)
return (short)(32 - __builtin_clz(t));
else
return 0;
}
但是,由于 abs() 函数需要分支,所以它有点慢。我尝试使用不带分支的 abs() 代替,但它甚至更慢,因为它包含至少 3 个算术指令。所以我希望也许有一种有效的算法可以准确地找到我需要的东西。
【问题讨论】:
-
@LMGTFY 正如我在问题中所说 - 这种方法比标准库中的 abs() 慢
-
您没有说明您尝试了哪个无分支版本 :)
-
@larsman inline myabs {unsigned int r; int const mask = x >> sizeof(int) * 8 - 1; return r = (x + mask) ^ mask;} 但这与问题无关。我不是在寻找一个 abs(),而是在寻找一种完全避免它的算法。
-
这段代码能做它应该做的吗?它会给出 log2(1) = 1,这似乎不对。
-
@AndreasBrinck 谢谢!我称它为 log2,但我真正的意思是在数组中的最大幅度元素中设置的最高有效位的位置。所以,应该是 ceil(log2(abs(maxElem(L))))
标签: c algorithm math optimization arm