Home > other >  Combine a uint32 with 32 MSB of uint64 to get a value
Combine a uint32 with 32 MSB of uint64 to get a value

Time:10-11

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:

  1. 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));
}

https://godbolt.org/z/YxxTM5f6E

  • Related