简体   繁体   English

C中的按位运算符

[英]bitwise operators in C

I have written a code for swapping bit positions(source bit and destination bit).. it is working fine.. But is there any optimized code to do this? 我已经编写了一个用于交换位位置(源位和目标位)的代码..它工作正常..但是有没有优化的代码来执行此操作?

int bit_swap(int num, int sbit, int dbit)
{
if(num & (1 << sbit) == num & (1 << dbit))
return num;
else
return (num ^ ((1 << sbit) | (1 << dbit)));
}

Here.. num is the input number.. sbit is the source bit position and dbit is the destination bit position.. 这里.. num是输入数字.sbit是源位位置,dbit是目标位位置。

Is there any way to write this code in a single line without using if and else 有没有办法在不使用ifelse的情况下在一行中编写此代码

You are making the classical mistake in thinking that less lines in C means more optimised code. 你认为C中较少的行意味着更优化的代码,这就是经典的错误。

You should really examine the assembler output and profile your code to see if it's an actual bottleneck. 您应该检查汇编器输出并分析您的代码,看它是否是一个真正的瓶颈。

What I tend to do is optimise for readability first then only attack performance if it becomes an issue. 我倾向于做的是优化可读性,然后只有攻击性能才会成为问题。 So, a more readable solution (in my not so humble opinion) would be something like: 因此,更可读的解决方案(在我不那么谦虚的意见中)将是这样的:

unsigned int bit_swap (unsigned int num, unsigned int pos1, unsigned int pos2) {
    // Swapping identical bit positions is a no-op.

    if (pos1 == pos2)
        return num;

    // Get masks from bit positions.

    unsigned int mask1 = 1 << pos1;
    unsigned int mask2 = 1 << pos2;

    // Get bit truth values.

    int bit1_was_set = ((num & mask1) != 0);
    int bit2_was_set = ((num & mask2) != 0);

    // Clear and set first bit (set only if second bit was originally set).

    num = num & ~mask1;
    if (bit2_was_set)
        num = num | mask1;

    // Do the same for other bit.

    num = num & ~mask2;
    if (bit1_was_set)
        num = num | mask2;

    // Return the value with swapped bits.

    return num;
}

Despite having far more lines than your approach, you may well find the insanely optimising compilers available nowadays will give you similar code under the covers. 尽管拥有比您的方法更多的线路,您可能会发现现在可用的疯狂优化编译器将为您提供类似的代码。

What you almost certainly will discover is that non-C-guru people (and possibly yourself, six months from now) will be able to understand your source code better than a single line multi-bitwise-operator variant. 您几乎肯定发现,非C-guru人(可能是您自己,六个月后)将能够比单行多位运算符变体更好地理解您的源代码。

No conditional version. 没有条件版本。

int bit_swap(int num, int sbit, int dbit)
{
    int sval = !!(num & (1 << sbit));  // sets to 1 iff the s-bit is already set
    int dval = !!(num & (1 << dbit));  // sets to 1 iff the d-bit is already set

    int xorval = (sval ^ dval); // sets to 1 if (sval != dval), otherwise 0

    // so if xorval is 1, then it will toggle the bits at the S and D positions
    // otherwise, the expression below evalutes to "num" that was passed in
    return (num ^ ((xorval << sbit) | (xorval << dbit)));
}

I came up with 我想出来了

unsigned swapBits(unsigned num, int sbit, int dbit)
{
  return ( num &               // All bits
    ~((1<<sbit) | (1<<dbit)))  // Except sbit and dbit
    | (((num>>sbit)&1)<<dbit)  // but with sbit moved to dbit
    | (((num>>dbit)&1)<<sbit); // and with dbit moved to sbit
}

I did have an ARM in mind, with its cheap shifts. 我确实有一个ARM,它的廉价转变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM