利用位运算符有哪些好方法?

发布于 2024-10-29 16:47:31 字数 62 浏览 1 评论 0原文

我经常遇到使用按位运算符来完成快速、简单且优雅的事情的人。我想学习一些有用的技巧。最有用的位运算符有哪些情况?

I constantly meet people using bitwise operators to do quick, easy and elegant things. I'd like to learn some useful tricks. What are some of the most useful bitwise operator cases?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

请别遗忘我 2024-11-05 16:47:31

常数时间 2 次幂:

x = 1 << n; // x = pow(2, n)

Constant time 2-exponentiation:

x = 1 << n; // x = pow(2, n)
浅沫记忆 2024-11-05 16:47:31

虽然我总体上同意 Michael McGowan 的观点,但位调整技巧在某些情况下可能非常有用,例如在对不具备所有常用指令的嵌入式硬件进行编程时。在将程序编码到定理证明器(例如 SMT 求解器)中时,我也很好地利用了此类技术,但它并不支持我想要使用的所有操作。

在寻找问题的按位解决方案时,我的第一站是网站 bit twiddling hacks 。它有很多适用于许多最常见技术的代码片段。

还有一本书Hacker's Delight 深入介绍了一些按位技术。

While I agree with Michael McGowan in general, bit twiddling hacks can be very useful in certain situations, for instance when programming embedded hardware which doesn't have all the usual instructions. I've also had good use for such techniques when encoding programs into theorem provers such as SMT solvers, which didn't support all the operations I wanted to use.

My first stop when looking for a bitwise solution to a problem is the site bit twiddling hacks. It has quite a few code snippets for many of the most common techniques.

Then there's also the book Hacker's Delight covers a few bitwise techniques in depth.

阳光①夏 2024-11-05 16:47:31

我在这里发现了一些有趣的按位运算集合:
http://graphics.stanford.edu/~seander/bithacks.html

I found some interesting bitwise operations collection at this place:
http://graphics.stanford.edu/~seander/bithacks.html

平生欢 2024-11-05 16:47:31

按位技巧(用于非位集操作)

|运算符

Covert Upper Case to lower Case letter

     char A[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     int n= strlen(A);
     for(int i=0;i<n;i++){
        if(A[i]>='A' && A[i]<='Z'){
            A[i] |= ' '; //A[i]=A[i]  | ' ';
        }
     }
     printf("%s\n",A);

输出

abcdefghijklmnopqrstuvwxyz

解释:

 ‘A’ = b01000001
|‘ ‘ = b00100000
----------------
       b01100001 =‘a’  

&运算符

Covert Lower Case to Upper Case Letter

     char A[] = "abcdefghijklmnopqrstuvwxyz";
     int n= strlen(A);
     for(int i=0;i<n;i++){
        if(A[i]>='a' && A[i]<='z'){
            A[i] &= '_';
        }
     }
     printf("%s\n",A);

输出

ABCDEFGHIJKLMNOPQRSTUVWXYZ

解释:**

 ‘a’ = b01100001
&‘_‘ = b11011111
----------------
       b01000001 =‘A’  

Determine if a Integer is odd or even

int n=100;
printf("%s\n", n&1?"odd":"even");
n=33;
printf("%s\n", n&1?"odd":"even");

输出:

even
odd

解释: 如果 n 为奇数,则 (n&1) 返回 1;如果 n 为偶数,则返回 0。

如果 n 是奇数,则二进制表示中 n 的最后一位将始终为 1。这就是为什么当我们 & 时它与 1 的结果变为 1。如果 n 甚至是二进制表示中 n 的最后一位,则始终为 0。这就是为什么当我们 & 时它与1的结果变成0。

(例如(奇)xxxxx1&1=1,(偶)xxxxx0&1=0)

^运算符

Toggle Case

     char A[] = "AbCdEfGhIjKlMnOpQrStUvWxYz";
     int n= strlen(A);
     for(int i=0;i<n;i++){
        A[i] ^= ' ';
     }
     printf("%s\n",A);

输出

aBcDeFgHiJkLmNoPqRsTuVwXyZ

解释:**

 ‘A’ = b01000001
^‘ ‘ = b00100000
----------------
       b01100001 =‘a’  

 ‘a’ = b01100001
^‘ ‘ = b00100000
----------------
       b01000001 =‘A’  

Swap two number without temp

int x=12, y=20;
printf("%d %d\n",x, y);
x^=y;   //x=x^y
y^=x;   //y=x^y
x^=y;   //x=x^y
printf("%d %d\n",x, y);

输出:

12 20
20 12

**解释:**

x=12 y=20
now for x=x^y
 12 = b01100
^20 = b10100
-------------
  x = b11000

now for y=x^y
  x = b11000
^20 = b10100
-------------
  y = b01100 =12 (swapped)

now for y=x^y
  x = b11000
 ^y = b01100
-------------
  x = b10100 =20 (swapped)

<<运算符

Multiply by 2n

int n=3;
int b = 4<<n;
printf("%d\n",b);

输出: 32

解释: 4x23 =32

4 in binary 100
100<<3 (right shift 3 times) will be 100000
100000 is equivalent to 32

Set value 2n

int n=3;
int b = 1<<n;
printf("%d\n",b);

输出: 8

解释: 1*23 =8

>>>运算符

Divide by 2n

int n=3;
int b = 32>>n;
printf("%d\n",b);

输出: 8

解释: \frac{32}{2^{^{3}}}= 4

32 in binary 100000
100000>>3 (left shift 3 times) will be 000100
100 is equivalent to 4

Bitwise tricks (for non-Bitset Operation)

| Operator

Covert Upper Case to lower Case letter

     char A[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     int n= strlen(A);
     for(int i=0;i<n;i++){
        if(A[i]>='A' && A[i]<='Z'){
            A[i] |= ' '; //A[i]=A[i]  | ' ';
        }
     }
     printf("%s\n",A);

Output

abcdefghijklmnopqrstuvwxyz

Explanation:

 ‘A’ = b01000001
|‘ ‘ = b00100000
----------------
       b01100001 =‘a’  

& Operator

Covert Lower Case to Upper Case Letter

     char A[] = "abcdefghijklmnopqrstuvwxyz";
     int n= strlen(A);
     for(int i=0;i<n;i++){
        if(A[i]>='a' && A[i]<='z'){
            A[i] &= '_';
        }
     }
     printf("%s\n",A);

Output

ABCDEFGHIJKLMNOPQRSTUVWXYZ

Explanation:**

 ‘a’ = b01100001
&‘_‘ = b11011111
----------------
       b01000001 =‘A’  

Determine if a Integer is odd or even

int n=100;
printf("%s\n", n&1?"odd":"even");
n=33;
printf("%s\n", n&1?"odd":"even");

Output:

even
odd

Explanation: (n&1) returns 1 if n is odd and returns 0 when it is even.

If n is odd the last bit of n in binary representation will be always 1. that is why when we & it with 1 the results become 1. If n is even the last bit of n in binary representation will be always 0. that is why when we & it with 1 the results become 0.

(eg. (odd) xxxxx1&1=1, (even) xxxxx0&1=0)

^ operator

Toggle Case

     char A[] = "AbCdEfGhIjKlMnOpQrStUvWxYz";
     int n= strlen(A);
     for(int i=0;i<n;i++){
        A[i] ^= ' ';
     }
     printf("%s\n",A);

Output

aBcDeFgHiJkLmNoPqRsTuVwXyZ

Explanation:**

 ‘A’ = b01000001
^‘ ‘ = b00100000
----------------
       b01100001 =‘a’  

 ‘a’ = b01100001
^‘ ‘ = b00100000
----------------
       b01000001 =‘A’  

Swap two number without temp

int x=12, y=20;
printf("%d %d\n",x, y);
x^=y;   //x=x^y
y^=x;   //y=x^y
x^=y;   //x=x^y
printf("%d %d\n",x, y);

Output:

12 20
20 12

**Explanation: **

x=12 y=20
now for x=x^y
 12 = b01100
^20 = b10100
-------------
  x = b11000

now for y=x^y
  x = b11000
^20 = b10100
-------------
  y = b01100 =12 (swapped)

now for y=x^y
  x = b11000
 ^y = b01100
-------------
  x = b10100 =20 (swapped)

<< operator

Multiply by 2n

int n=3;
int b = 4<<n;
printf("%d\n",b);

Output: 32

Explanation: 4x23 =32

4 in binary 100
100<<3 (right shift 3 times) will be 100000
100000 is equivalent to 32

Set value 2n

int n=3;
int b = 1<<n;
printf("%d\n",b);

Output: 8

Explanation: 1*23 =8

>> operator

Divide by 2n

int n=3;
int b = 32>>n;
printf("%d\n",b);

Output: 8

Explanation: \frac{32}{2^{^{3}}}= 4

32 in binary 100000
100000>>3 (left shift 3 times) will be 000100
100 is equivalent to 4
﹏雨一样淡蓝的深情 2024-11-05 16:47:31

通常使用这样的技巧并不是一个好主意。现代编译器经常在可能的情况下在幕后做这种事情。也就是说,有时您知道编译器不知道(也许在运行时保证特定值是 2 的幂)。如果您确定尝试这些技巧是个好主意,这里有一些有用的小窍门。

Usually it's not a good idea to use such tricks. Modern compilers often do this kind of stuff behind the scenes when possible. That said, sometimes you have knowledge that the compiler doesn't (maybe that a particular value is guaranteed at runtime to be a power of 2). If you determine that it is a good idea to try such tricks, here are useful bit twiddling hacks.

听,心雨的声音 2024-11-05 16:47:31

您始终可以使用左移按位运算符 (<<) 将给定数字乘以 2。

对于前任 -

   public class abc {public static void main (String[] arg)
{
    int a = 650;
    int doubleOfa = a<<1;
    System.out.println(a);
    System.out.println(doubleOfa);

    }
}

You can always make use of left shift bitwise operator (<<) to mutiply the given number by 2.

For Ex -

   public class abc {public static void main (String[] arg)
{
    int a = 650;
    int doubleOfa = a<<1;
    System.out.println(a);
    System.out.println(doubleOfa);

    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文