6

考虑:

#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
4

5 回答 5

10

左移不会截断数字以适合原始数字的长度。要获得90,请使用:

(a<<4) & 0xff

0x59是一个int并且可能在你的平台上它有sizeof(int)==4。然后是一个0x00000059。将其左移 4 给出0x00000590.

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

于 2013-03-06T09:02:53.793 回答
6

你将一个十六进制数向左移动了 4 位,所以你得到了 590,这是正确的。

你有过

000001011001    

左移 4 位

010110010000

是 590 的十六进制数

10010000

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

于 2013-03-06T08:58:07.020 回答
4

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

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

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

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

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

于 2013-03-06T09:02:44.437 回答
1

你正在使用 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
于 2013-03-06T09:05:21.637 回答
0

那么你能告诉我我应该怎么做才能得到0x90的输出吗?我需要将最后 4 位移到前 4 位,最后添加 0

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

unsigned char a=0x59;
macro(a)

但是当使用int结果是0x590 错误不与使用<<is与选择类型有关。(或滥用宏?)

于 2013-03-06T09:04:36.860 回答