unexpected value on bit manipulation with macro in C [on hold]

问题内容:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

#define PTXSHIFT 12 
#define PTX(va) (((uint) (va) >> PTXSHIFT) & 0x3FF)

int main()
{
    printf("0x%x", PTX(0x12345678));
    return 0;
}

I tested it on online compiler and I’m getting a compiler error saying 'uint' is undeclared. I guess C online compiler can’t import stdint.h. : https://www.onlinegdb.com/online_c_compiler

So I manually put values: (0x12345678>>12)&0x3FF.

Problem the output is 0x345, can you explain why?

0x12345678 >> 12 = 0x12345 (??)
0x12345 & 0x3FF = 0x345 (??)

UPDATE Sorry for the confusion guys.
I’m asking for the explanation on the output 0x345. I’m confused why 0x12345678 >> 12 is 0x12345 and 0x12345 & 0x3FF is 0x345.

问题评论:

1  
It includes stdint.h just fine. The problem is that there is no such alias uint defined to be in it.
    
uint is undeclared because there is no such thing as uint in any of the header files… Voting to close as simple typo.
1  
Are you asking about the build error, or the unexpected output? Please keep it to one question per question.
1  
@JohnBaek no, the unit of the shift amplitude is one bit, not four bits. 0x12345678 >> 4 is 0x1234567.
1  
I thought 0x12345678>>1 is 0x1234567 >>1 shifts one bit, not an entire hex digit, which is 4 bits. 0x12345678>>1 is going to be something like 0x9....C.

答案:

答案1:

You can get the same result using

#define PTX(va) (((uint32_t) (va) >> PTXSHIFT) & 0x3FF)

The answer is expected because of the Bitwise and operation as mentioned in other answer.

      1    2    3    4    5
    0001 0010 0011 0100 0101
    0000 0000 0011 1111 1111
      0    0    3    F    F
AND
    --------------------------
    0000 0000 0011 0100 0101

The shift operation is shifting the bits of an unsigned int to the right filling the left with 0‘s.

0x12345678

0001 0010 0011 0100 0101 0110 0111 1000

Shifts by 12


0001 0010 0011 0100 0101 [0110 0111 1000]---->

[0000 0000 0000]0001 0010 0011 0100 0101

  0    0     0    1    2   3     4     5

That explains why 0x12345678 >> 12 = 0x12345

Truth table of AND

And if you don’t understand the AND operation then it will be the truth table it should know about.

A | B | A & B
--+---+------
0 | 0 |  0
0 | 1 |  0
1 | 0 |  0
1 | 1 |  1

答案评论:

    
He doesn’t understand the shift operation either, see his updated question.
    
@MichaelWalz.: Yes it seems so that’s why added.
    
I just misunderstood that hexadecimal represented 0x1 => 0001. Thanks codrredoc for the concrete explanation
– John Baek
3 hours ago
    
@JohnBaek.: Yes

答案2:

What output did you expect?

Let’s look the bitwise AND, nibble by nibble, in hex:

     1 2 3 4 5
AND      3 f f
--------------
         3 4 5

or in binary, which might help:

         0011 0100 0101
     AND 0011 1111 1111
     ------------------
         0011 0100 0101

It should be obvious that 3 & 3 is 3, just as 4 & f is 4 and so on.

答案评论:

    
Why is 4&f = 4???? 3&3 is obvious to me.
– John Baek
3 hours ago
    
@JohnBaek: You are kidding, aren’t you?
    
I’m just confused. f is 15 and 4 is 4. I haven’t used C for 3 years. I’m trying hard to bring it back,
– John Baek
3 hours ago
    
@JohnBaek it’s unrelated to C, you should understand what hexadecimal notation and what bitwise logical operators (and, or) are.
    
@WedaPashi Yeah, fixed that typo even before I read your comment. Thanks anyway.

原文地址:

https://stackoverflow.com/questions/47753207/unexpected-value-on-bit-manipulation-with-macro-in-c

Tags:

添加评论