- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
给定一个 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 个算术指令。所以我希望也许有一种高效的算法可以准确地找到我需要的东西。
最佳答案
看到你在 ARM 平台上工作,你可以在 2 条指令中使用以下 abs
的实现:
EORS r1, r1, r1, ASR #32 (x = x ^ (x >> 32); carry_flag = sign_bit)
ADC r1, r1, #0 (add the sign_bit to x)
如果你可以容忍计算中+/-1的误差,放弃第二条指令;那么,你就可以用C来表达了:
int abs_almost_exact(int x)
{
return x ^ (x >> 32);
}
但是,更大的问题是循环。您可能会从展开中获益良多(因为每次迭代都没什么可做的):
do { // assuming len is even!
int value1 = *p++;
int value2 = *p++;
value1 = abs(value1); // or replace abs by the hand-made version
value2 = abs(value2);
t |= value1;
t |= value2;
len--;
}
while (len > 0);
注意:我将 while {}
替换为 do {} while
因为我使用的编译器(ARM 编译器)以这种方式生成更好的代码。
另请注意,从内存(在我使用的处理器上)加载short
变量时,ARM 有 2 个时钟周期的延迟。因此,最小展开因子为 3(但无论如何您都应该尽可能多地展开)。
哦,您的处理器是否支持从内存中读取短
(半字)变量?我听说过一些非常老的处理器无法做到这一点。如果您遇到这种情况,您应该更改代码以一次加载 2 个值(1 个字),并使用一些位操作来分隔它们。
关于c - 查找数组中最大幅度元素的 MSB 集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13515700/
我希望将 LSB、MSB 的字节数组转换为 int 的数组 目前,我正在使用 for 循环并单独转换每组值, void ConvertToInt(int OutArray[], byte InArra
我想分配一个 std_logic_vector 而不给出界限。像这样: constant xy: std_logic_vector := "100111"; 当我想访问单个位时: xy(0), xy(
我检查了用于反转位顺序的 SWAR 算法(SIMD W在 A Rregister 中) unsigned int 的。 signed int 有类似的东西吗? 最佳答案 该算法仅适用于无符号整数,因为
当我使用下面的代码更改 32 位时,或者当 bitc 等于 31 时,它给出 -2147483643。 它似乎将所有 0 更改为 1,而不是仅将最后一个 0 更改。我怎样才能在代码中解决这个问题?预先
对于给定的数字 unsigned int a = 1203; 仅对上述示例增加最重要的小数位 a = 2203; 如何实现? 我是这样开始的 for (n=a; n; n/=10){ b = n%10
以unsigned char为例。 它的范围是0 到 255。 如果我尝试在其中存储 256,将发生以下情况:- 256 的二进制文件 100000000 由于它由9位组成,因此MSB 1将被丢弃,它
我正在通过将位打包到一个 uint 数组中来实现一个位向量。 getBit(index)函数执行 (array[cell] & (1 > bit获取是否已设置位。这适用于除 MSB 之外的所有位。它不
我想知道一个字节的第一位是什么值。 例如: 我有 byte m = (byte) 0x8C; 我怎么知道第一位是 1 还是 0? 谁能帮帮我? 最佳答案 这取决于你所说的“第一位”是什么意思。如果您的
我需要将十六进制字符串中的 MSB 和其余位分开。例如:我有一个十六进制字符串 a2,相当于 1010 0010。我想分离出 MSB(在本例中为 1),其余数字转换为十进制。我想我可以做这样的事情:
我有一个 20 个字/字节的数组,存储一个 160 位数。如何找到从 msb 开始的第一个非零位。我需要找到位的位置,然后相应地从第一个'1'位置开始我需要做一些操作。 最佳答案 如果您使用的是 gc
我有一个函数返回 1 Byte uint8_t fun(); 该函数应该运行 9 次,所以我得到 9 字节 我想将最后一个 8 作为 4 short values 这里我所做的,但是我'我不确定我得到
我正在努力转换在特定微 Controller 上运行的程序,并使其适应在树莓派上运行。我已经成功地从我一直在使用的传感器中提取值,但现在我遇到了一个问题,我认为这是由我无法理解的几行代码引起的。我已经
所以我想切换我数字的最高有效位。这是一个例子: x = 100101 then answer should be 00101 我有一台 64 位机器,因此我不希望答案是 100000....10010
给定一个 len 类型的 signed short 元素数组,它是在数组中的最大绝对值元素中找到设置的最高有效位的位置。例如,如果数组 L 包含 {-134, 123, 0, -890} 那么 f(L
在中断子程序(每 5 µs 调用一次)中,我需要检查一个字节的 MSB 并将其复制到该字节的其余部分。 我需要做类似的事情: if(MSB == 1){byte = 0b11111111} else{
我正在交叉编译 MIPS 处理器(little-endian arch)的开源库 oRTP。我的开发系统是i386 linux。我将配置脚本运行为 ./configure --host=mips-li
在两个有符号整数的二进制加法中,如果进出 MSB 列的进位不匹配,则会出现有符号溢出。 这条规则背后的逻辑是什么?为什么进位和执行应该匹配才能得到正确的结果。请解释一下。 最佳答案 显然有两种不匹配的
我有一个二进制协议(protocol),它将每个有效负载字节的 MSB 提取到 MSB 集合字节(七进制)中进行传输,并在接收器端重新注入(inject) MSB。有效负载由 n 个四字节帧组成,具体
我有以下代码用于从非负整数获取 MSB(最高有效位),更具体地说是 Int32: private static readonly int[] powersOf2 = new int[]
我以 2 字节短值的十六进制值形式获取数据,但交换值后丢失了。 signed short value = 0x0040; value = (value*0.5) - 40; convertMSB
我是一名优秀的程序员,十分优秀!