c - 如果 x>0 且 r(x) = 2x,则实现有符号到无符号映射 r(x)= 2x-1 的更快方法是什么

标签 c performance compression bit-manipulation

可以使用二进制补码等常用技术将有符号整数映射到无符号整数。不幸的是,他们无法将小负整数映射到小数字。对于压缩算法,我们通常希望尽可能保留数字的绝对值:小负数和正数必须映射到小数字。

如果 x<0,则流行的映射为 r(x)= -2x-1;如果 x>=0,则 r(x) = 2x。 (类似的是,如果 x<=0,则 r(x) = -2x;如果 x>0,则 r(x) = -2x。)

这张 map 的实现比较简单,速度相对较慢。当然比仅仅将有符号整数转换为无符号整数(默默地应用补码)要慢得多。

最快的方法是什么?

最佳答案

默默地应用二进制补码,是的,在大多数现代平台上,这只是一个nop,编译器只是以不同的方式解释您的数据。所以这真的很难被击败。

为了便于比较,如果您能提供一些基准就好了......

如果我没记错的话2 * abs(x) + signbit可以通过位的循环左移来完成。因此,如果您的平台有这样的指令,那么使用内联汇编器应该很容易实现,并且最后应该只产生一条指令。

编辑:我错了,这个简单的事情只适用于负数的符号和值表示。

对于二进制补码,如果输入为负,则必须对旋转结果求负。类似的东西

inline uint64_t rotateL(uint64_t x) {
  asm ("rolq %0" : "=r" (x) : "r" (x));
  return x;
}

inline uint64_t value(uint64_t x) {
  uint64_t ret = rotateL(x);
  return (ret % UINT64_C(2))
    ? -ret
    : ret;
}

我研究了 gcc 生成的汇编程序。看起来不错,只有 5 条说明

rolq    %rax
movq    %rax, %rdx
negq    %rdx
testb   $1, %al
cmovne  %rdx, %rax

关于c - 如果 x>0 且 r(x) = 2x,则实现有符号到无符号映射 r(x)= 2x-1 的更快方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3557599/

相关文章:

c - 关于 Spectre 示例,虚拟/物理地址如何工作?

java - (Java) 快速插入、删除和随机选择的数据结构

iphone - 加密并压缩 iPhone 应用程序包中的 html 代码,首次启动时解压

video - ffmpeg 将 mov 转换为 mp4 而不会降低比特率

c - 删除资源

c++ - 如何注释#if、#else、#endif 预处理器构造?

c++ - 我在哪里可以找到世界上最快的 atof 实现?

javascript - 如何以更好的性能替换字符串中的大量单词?

c# - 你应该压缩 html 页面吗?如果是这样,如何在 .net 中做到这一点?

c - 置换 i 和 T[i]