I have a timestamp that is truncated and I am getting the value as uint32. In order to recover it I will need to combine it with the MSB(bit63~32) of the RTC time (uint64) that I am getting. An example of values is this: uint32_t sensor_ts=1897792412; uint64_t clock_ts=1665471940315;
How could I form the new timestamp?
CodePudding user response:
uint64_t tstmp = sensor_ts | (clock_ts & ((~(uint64_t)0) << 32));
You should use bit masks here. To get the upper 32 bits of clock_ts
, you can use a mask, with the upper 32 bits set. In my example I do this with an fully set uint64_t (111..111, 64 times 1). I shift it to the left by 32 bits, so the lower 32 bits are 0 (111...000, 32 times 1 and 32 times 0). Now I use the bitwise and operator, to zero out the lower 32 bits of clock_ts. And finally use the bitwise or operator to create the combined timestamp.
CodePudding user response:
- When you think binary do not use decimal numbers only hex or octal.
uint32_t sensor_ts = 0x711e039c; uint64_t clock_ts = 0x00000183c5dd06dbll;
To replace upper 32bits:
You can use bitwise operations
uint64_t combine(const uint32_t x, uint64_t y)
{
y &= (((uint64_t)1 << 32) - 1); // reset upper 32 bits
y |= (uint64_t)x << 32; // set upper 32 bits
return y;
}
or union if you know the endianness (in this case little endian)
uint64_t combine1(const uint32_t x, uint64_t y)
{
union
{
uint64_t y;
uint32_t x[2];
}u64 = {.y = y};
u64.x[1] = x;
return u64.y;
}
https://godbolt.org/z/asdTEK9Ka
Or to replace lower 32bits:
uint64_t combine(const uint32_t x, uint64_t y)
{
y &= ~(((uint64_t)1ULL << 32) - 1); // reset lower 32 bits
y |= x; // set lower 32 bits
return y;
}
uint64_t combine1(const uint32_t x, uint64_t y)
{
union
{
uint64_t y;
uint32_t x[2];
}u64 = {.y = y};
u64.x[0] = x;
return u64.y;
}
int main(void)
{
uint32_t sensor_ts=1897792412; uint64_t clock_ts=1665471940315;
printf("6"PRIx32" 6"PRIx64"\n", sensor_ts, clock_ts);
printf("6"PRIx64" 6"PRIx64"\n", combine(sensor_ts, clock_ts), combine1(sensor_ts, clock_ts));
}