sam sam - 1 month ago 16
C Question

how to convert 64 bit number to a 8 bit

How would I convert a 64 bit number (

0xffffffffffffff8c
) to an 8 bit number (
0x8c
). My code:

uint64_t val = 0xffffffffffffff8c;
uint8_t var = (uint8_t) (val & 0x0000FF);


Am I doing it the right way?

Answer
uint64_t val = foo();

Consider 4 below methods, all well behaved because assigning a value to an unsigned type is well defined, even if the value is outside the range of the destination. Effectively it is the Euclidean mod of "one plus the max value of the destination type".

Note: The leading 0s in mask constant 0x0000FF are not needed. Use leading zeros as desired to convey clarity. Could use 0xFF or 0x00000000000000FF.


OP's original: No problem, but a bit verbose. As long as val is some integer type, & is allowed.

uint8_t var = (uint8_t) (val & 0x0000FF);

Cast, no mask. Casting to (uint8_t) is a mask of 0xFF. In general, masking should be avoided as it has surprising effects in porting code. Not so when casting to an unsigned fixed width type as in this simply example.

uint8_t var_nm = (uint8_t) val;

Mask, no cast. Like the above. Narrowing of the value is explicitly coded.

uint8_t var_nc = val & 0xFF;

No cast, no mask. This works buts may generate a warning such as below when the pedantic [-Wconversion] or equivalent is used. It is not clear that code expects a narrowing.

// warning: conversion to 'uint8_t {aka unsigned char}' from 'uint64_t 
// {aka long long unsigned int}' may alter its value [-Wconversion]
uint8_t var_nc_nm = val;

The goal of coding is to 1) do the function 2) do it reasonable efficient 3) promote clarity of intent both now and in the future. Recommend as it clearly conveys code's intention to narrow the value of the range 0-FF

uint8_t var_nc = val & 0xFF;

As a second choice, go for simply

uint8_t var = val;

Expect the same executable code to be generated.

--

Minor: the names val and var are too generic.