BillG - 4 months ago 13

C Question

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`

`{ (x,y,z)< 256}`

`x,y,z`

`2^10 (1024)`

`(x,y,z)<1024`

Any ideas?

Answer

Rather than use

*signed*types, use*unsigned*types. A lot less trouble. @OlafThe 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));
```