嚴華 发表于 2025-2-12 14:05:15

c语言:取绝对值

假设我们有一个 long 范例的变量 l,我们希望规复其绝对值。以下是两种方法的对比:
方法1:使用条件语句

这个很好理解,负数时取负运算 ,用于数值的符号反转。
long abs_value(long l) {
    if (l < 0) {
      return -l;
    } else {
      return l;
    }
} 方法2:使用位利用

long abs_value(long l) {
    long s = l >> 63;// 获取符号位
    l = (l + s) ^ s;   // 恢复绝对值
    return l;
}       l为正数时,s=0;  (l+s)^s = l^0=l;对于任何整数与 0 举行按位异或利用的效果总是 其自己。
      l为负数时,s=-1,即0xffff ffff ffff ffff;
      这是由于long l的最高位为符号位,负数的最高位为1;右移利用会将变量的二进制表现向右移动指定的位数,空出的位数会用符号位的值来填充,l>>63,左侧空位全补1就得到0xffff ffff ffff ffff,该值对应-1。
在盘算机中,负数以补码的形式表现。对于一个负数 x,其补码表现为:

[*] 取反(按位取反)。
[*] 加1。
   s=-1时, (l+s)^s = (l-1)^0xffff ffff ffff ffff  正好是负数取补码的逆过程,以是相当于获取了负数的绝对值。

方法2的优势:
1. 避免条件分支

使用条件语句(如 if 语句)会导致代码中出现分支。在现代处理器中,分支预测失败大概会导致性能降落。通过使用位利用,可以避免条件分支,从而提高代码的执行效率。
2. 提高性能

位利用通常比条件分支更快,由于它们直接在寄存器级别举行利用,而不需要举行复杂的控制流判断。这在性能敏感的应用中尤其告急。
3. 淘汰代码复杂性

固然位利用大概看起来有些复杂,但它们实际上可以淘汰代码的复杂性,特别是在处理整数利用时。位利用通常更简洁,且不需要额外的变量或复杂的逻辑。

但是实际测试时,还是方法1的性能更高一些:
xxx@:~/test/c-func$ ./a.out
Time taken by abs_value_if: 4.517215 seconds
Time taken by abs_value_bit: 4.865139 seconds
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: c语言:取绝对值