【问题标题】:Left shift operator in CC中的左移运算符
【发布时间】:2020-01-07 11:39:59
【问题描述】:

考虑:

#include <stdio.h>
#define macro(a) a=a<<4;

main()
{
    int a = 0x59;
    printf("%x", a);
    printf("\n");
    macro(a)
    printf("%x", a);
}

对于上面的代码,我得到以下输出:

59
590

为什么我没有得到以下输出作为左移操作?

59
90

【问题讨论】:

  • 那么你能告诉我我应该怎么做才能得到输出为 90..我需要将最后 4 位移动到前 4 位,在末尾添加 0。
  • 如果您希望它只是 2 个十六进制数字,请尝试将 a 更改为 unsigned char 而不是 int
  • 左移4相当于将数字乘以2、4倍。即 59 * 2 * 2 * 2 * 2 = 590(以 16 为基数)。你的输出是正确的。
  • #define 宏(a) a=a

标签: c bit-shift


【解决方案1】:

左移确实截断数字以适合原始数字的长度。要获取90,请使用:

(a<<4) & 0xff

0x59 是一个int,可能在你的平台上它有sizeof(int)==4。然后是0x00000059。将其左移 4 得到0x00000590

此外,在处理位运算符时,养成使用unsigned int 类型的好习惯,除非您知道自己在做什么。他们在右移等情况下有不同的行为。

【讨论】:

    【解决方案2】:

    您将一个十六进制数左移 4 位,得到 590,这是正确的。

    你有

    000001011001    
    

    左移 4 位

    010110010000
    

    是 590(十六进制)

    10010000
    

    在十六进制中是 90,因此您可能想要删除 0101,如 phoeagon 所示

    【讨论】:

      【解决方案3】:

      如果您将 %x 更改为 %d,则在您的 printf 中 你得到一个 =89 左移后你会得到 a = 1424

      通常用于十进制(以 10 为底)数字

      a = a<< n  is  a = a*2^n
      a = a>> n  is  a = a/2^n
      

      对于十六进制(以 16 为基数)数字,

      任何 n (左或右)的移位,都可以被认为是二进制等价位的相应移位。但这取决于 sizeof(int) ,用于给定的编译器。

      【讨论】:

        【解决方案4】:

        你正在使用 int 所以你有:

         000001011001  
        

        如果你将它向左移动 4,你会得到:

        010110010000
        

        如果您只想拥有前 8 位,则不必使用“int”,而是使用 unsigned char(或 char)

        #include<stdio.h>
        #define macro(a) a=a<<4;
        main()
        {
           unsigned char a=0x59;
           printf("%x",a);
           printf("\n");
           macro(a)
           printf("%x",a);            
        }
        

        如果您仍想使用 int 但只保留前 8 位,则可以使用掩码:

        #define macro(a) a=(a<<4) & 0xFF
        

        【讨论】:

        • #define 宏(a) a=(a
        • 我的错误。当然不能!!!! (我想每个人都按时犯了这个错误:D)
        【解决方案5】:

        所以你能告诉我我应该怎么做才能得到输出 作为0x90?我需要将最后 4 位移到前 4 位添加 0 最后

        如果您的类型只有 8 位,那么您可以将最后 4 位向左移动 4 位并将其替换前 4 位的唯一方法是。通常这是unsigned char 的情况,而不是int。你会得到0x90

        unsigned char a=0x59;
        macro(a)
        

        但是当使用int 时,结果是0x590 错误不在于&lt;&lt; 的使用,而在于类型的选择。 (或滥用宏?)

        【讨论】:

          猜你喜欢
          • 2013-03-28
          • 2022-11-03
          • 1970-01-01
          • 2014-08-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多