BillG BillG - 4 months ago 13
C Question

Store values in 64 bit integer in C

I got a program

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

int main(void)
{

int i;
int x = 128;
int y = 128;
int z = 2;
int32_t coordinates = x | (y << 12) | (z << 16);

fprintf(stdout, "x = %d\n", (coordinates & 0xFF));
fprintf(stdout, "y = %d\n", ((coordinates >> 8) & 0xFF));
fprintf(stdout, "z = %d\n", ((coordinates >> 16) & 0xFF));
}


That stores
x,y,z
in 32 bit register, but its successful ONLY for
{ (x,y,z)< 256}
. If I want it to be possible for
x,y,z
to get values of
2^10 (1024)
(so
(x,y,z)<1024
) how can this happen? I know that I should use a 64 bit register(?) but I am stuck on this, because something is going on with shifts.

Any ideas?

Answer
  1. Rather than use signed types, use unsigned types. A lot less trouble. @Olaf

  2. The below code allows x to have a 12-bit range before colliding with y. It allows y to have a 4-bit (16 - 12) range before colliding with z. It have troubles with a 16-bit int/unsigned.

    int32_t coordinates = x | (y << 12) | (z << 16);
    

To allow x,y,z to have a 10-bit range, shift y by 10 and z by 10+10.

 uint32_t coordinates = x | ((uint32_t)y << 10) | ((uint32_t)z << 20);

To exact the values:
(be sure to use the matching print specifier too.)

#include <inttypes.h>
...
fprintf(stdout, "x = %" PRIu32 "\n", (coordinates & 0x3FF));
fprintf(stdout, "y = %" PRIu32 "\n", ((coordinates >> 10) & 0x3FF));
fprintf(stdout, "z = %" PRIu32 "\n", ((coordinates >> 20) & 0x3FF));