6

I'm trying to cast a uint64_t (representing time in nanoseconds from D-day using a boost chrono high precision clock) to a uint32_t in order to seed a random number generator.

I just want the least significant 32 bits of the uint64_t. Here is my attempt:

uint64_t ticks64 = dtn.count(); // This has the ticks in nanosec
uint64_t ticks32_manual = ticks64 & 0xFFFFFFFF;
uint32_t ticks32_auto = (uint32_t) ticks64;
mexPrintf("Periods: %llu\n", ticks64);
mexPrintf("32-bit manual truncation: %llu\n", ticks32_manual);
mexPrintf("32-bit automatic truncation: %u\n", ticks32_auto);

The output of my code is as follows:

Periods: 651444791362198

32-bit manual truncation: 1331774102

32-bit automatic truncation: 1331774102

I was expecting the last few digits of the 32 and original 64-bit representations to be the same, but they are not. That is, I thought I would "lose the left half" of the 64-bit number.

Can anyone explain what's going on here? Thanks.

Btw, I've seen this link.

Community
  • 1
  • 1
Salmonstrikes
  • 737
  • 1
  • 6
  • 25
  • 6
    `I was expecting the last few digits of the 32 and original 64-bit representations to be the same, but they are not` -- That's because you're looking at the two numbers in a base 10 representation, not base two or any other representation that's divisible by two. You shouldn't have any expectation that the last few digits are going to be the same base 10 numbers. Using hex will work, though. – Robert Harvey Apr 02 '15 at 03:25
  • 3
    Replace `dtn.count()` with `651444791362198`. Change both `%llu` to `%016llx` and the `%u` to `%08x`. Rerun the program. Are you enlightened? – zwol Apr 02 '15 at 03:26
  • Oops. Yes. So I suppose (uint32_t) (651444791362198 % 1E6), then – Salmonstrikes Apr 02 '15 at 03:43
  • Or, for the full 32-bit range, (uint32_t) (time64 % UINT32_MAX). That would change the last few digits again, though. – Salmonstrikes Apr 02 '15 at 03:52
  • Nanoseconds from D-Day? Never seen that timing system before. Any particular time on D-Day? – Lightness Races in Orbit Apr 02 '15 at 09:57
  • @LightningRacisinObrit: I just used that in jest. According to the documentation, it gives you the time that has elapsed since Jan 1, 1970. I don't know the exact time, but I suspect it must be midnight. Also, 64-bits isn't enough to represent that time to now in nanoseconds. Thankfully, I just need the relevant LSBs for my purpose. – Salmonstrikes Apr 02 '15 at 10:51
  • 1
    @Salmonstrikes: That's called the UNIX epoch and, yes, it is midnight. And 64 bits are way more than enough to represent that duration. – Lightness Races in Orbit Apr 02 '15 at 11:19
  • Source: nanosecond-precision timing is my profession. Also, [this](http://coliru.stacked-crooked.com/a/80595728b62657e8) – Lightness Races in Orbit Apr 02 '15 at 11:25
  • @LightningRacisinObrit: Yes, you're right. I botched the calculations. 64-bits allows about 580 years' worth of nanoseconds, which should hopefully be sufficient. – Salmonstrikes Apr 02 '15 at 12:54

1 Answers1

8

As pointed out in the comments there's nothing wrong with the operation of your code, it's just that you're not visualizing the output correctly. Here's your code, corrected and runnable:

#include <cstdio>
#include <cstdint>

int main() {
  uint64_t ticks64 = 651444791362198llu;
  uint64_t ticks32_manual = ticks64 & 0xFFFFFFFF;
  uint32_t ticks32_auto = (uint32_t) ticks64;

  printf("Periods: %llX\n", ticks64);
  printf("32-bit manual truncation: %llX\n", ticks32_manual);
  printf("32-bit automatic truncation: %X\n", ticks32_auto);
}

And the output is:

Periods: 2507C4F614296
32-bit manual truncation: 4F614296
32-bit automatic truncation: 4F614296
Andy Brown
  • 11,766
  • 2
  • 42
  • 61