user968000
user968000

Reputation: 1843

Get last two bytes from a 64bit value

I am getting 0xABCDABCD.0.1 when I run the following code. I wanted to get the last two bytes 01b0 from val, but the output shows as 1. I am masking the last two bytes using : 0x000000000000FFFF

uint64_t val  = 0xabcdabcd010001b0;

int main() {


   printf("0x%X.%d.%x",(val&0xFFFFFFFF00000000)>>32, 
    (val&0x00000000FF000000)>>24,(val&0x000000000000FFFF));
   return 0;
}

Upvotes: 2

Views: 979

Answers (4)

Ken Y-N
Ken Y-N

Reputation: 15009

The problem is that the results of the bitmasks are uint64_t types. To print correctly, you need this code, online here:

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

uint64_t val  = 0xabcdabcd010001b0;

int main() {
   printf("0x%" PRIX64 ".%" PRId64 ".%" PRIx64,
    (val&0xFFFFFFFF00000000)>>32, 
    (val&0x00000000FF000000)>>24,
    (val&0x000000000000FFFF));
   return 0;
}

See the section "Format constants for the std::fprintf family of functions" on this page for more formats.

Upvotes: 1

lod
lod

Reputation: 1100

I took the liberty of rewriting the code for you, dropping the massive masks and adding the awful inttypes printf defines.

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

uint64_t val  = 0xabcdabcd010001b0;

int main() {
    printf("0x%" PRIX64 ".%" PRIx64 ".%04" PRIx64 "\n",
        val >> 32, 
        (val >> 24) & 0xFF,
        val & 0xFFFF
    );  
    return 0;
}   

Note that the only functional change is adding the leading zeros to the third print argument.

Upvotes: 1

Heavy
Heavy

Reputation: 1900

%X and %d require int arguments, but you are passing uint64_t. Try using PRIu64 and PRIx64 macros instead. See cpp.sh fiddle:

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

// ...

   printf("0x%" PRIx64 ".%" PRIu64 ".%04" PRIx64 "",
          (val&0xFFFFFFFF00000000)>>32, 
          (val&0x00000000FF000000)>>24,
          (val&0x000000000000FFFF)
          );

Upvotes: 0

Niloct
Niloct

Reputation: 9995

Perhaps this polished version can be of use to you:

#include <stdio.h>
#include <stdint.h>
uint64_t val = 0xabcdabcd010001b0;

int main() {
   void *p1, *p2, *p3;
   p1 = (void *) (val & 0xFFFFFFFF00000000 >> 32);
   p2 = (void *) (val & 0x00000000FF000000 >> 24);
   p3 = (void *) (val & 0x000000000000FFFF);
   printf("%p.%p.%p\n",p1, p2, p3);
   return 0;
}

Trick that a pointer type can handle those ints as addresses in a x64 machine.

Upvotes: 0

Related Questions