-2

Say, I have a profiler method that returns a uint64_t value in hexadecimal format. I want to display this value in decimal format.

Is there a simple way to do this without using standard c++ libraries? the expected output is in the range of microseconds. A sample value that I get from the profiler is 0x9f0340.

Patrick87
  • 27,682
  • 3
  • 38
  • 73
Naveen
  • 458
  • 1
  • 10
  • 29
  • Are you trying to reinterpret the bits as a double or just convert the number to a double? In your example, do you want the double to have the value 10421056.0? – mattnewport Aug 25 '15 at 20:08
  • Convert the number to double. I'll edit the question. – Naveen Aug 25 '15 at 20:11
  • 1
    'hexadecimal' is a string (ascii) format. uint64_t is a binary format. Which do you have? – Chris Dodd Aug 25 '15 at 20:17
  • @Naveen Your edited question is still unclear about what you are trying to accomplish. Try describing what the desired output is given your example input. If you are just trying to print the value as decimal rather than hex there is no need to convert to a double at all. – mattnewport Aug 25 '15 at 20:23
  • show us some real code – pm100 Aug 25 '15 at 20:26
  • Not sure what the downvote is for. I use a RDTSC class to profile a function inside a loop for it's execution time. A method inside the RSTSC class returns the hex number shown above which is in uint64_t format. I simply want to convert this into a floating point/double number. I assume the execution time is in order of milliseconds and that what I expect to see as the result of the conversion. I hope it is clear now. – Naveen Aug 25 '15 at 20:30
  • I'm confused about the "hexadecimal" part. `uint64_t` doesn't store hexadecimals, it store a 64-bit integer. If you see it as decimal, octal, hexadecimal, binary, roman numerals, whatever, is just decided by how you want to represent this value when you print them on a human readable way. – Havenard Aug 25 '15 at 20:30
  • I'm not sure what you want to accomplish, but if the idea is to read this 64-bits currently stored as `uint64_t`, *as if* it was a 64-bit `double`, you can try `*(double *)&value` where `value` is the `uint64_t` variable containing the information. – Havenard Aug 25 '15 at 20:32
  • @Havenard If I a do a reinterpret cast of 0x9f0340 to char will it read as 0x9f0340? If this is the case, how do I convert this hexadecimal number to double? – Naveen Aug 25 '15 at 20:34
  • 1
    Downvote is likely because the question is unclear. Given the decimal number 10 in a variable of type uint64_t do you want A) 10.0 in a variable of type double or B) 4.94066e-323 in a variable of type double (assuming little endian)? – user4581301 Aug 25 '15 at 20:35
  • 1
    Downvote and vote to close were from me. The reason is because half a dozen people are asking you whether you want to *convert the value from uint64 to double* or *interpret the bits in the uint64 as a double* and you have refused to say which of the two you want. – Patrick87 Aug 25 '15 at 20:39
  • @Naveen it is still not clear what you want to accomplish. It sounds like you perhaps also want to convert a value from rdtsc into a time in milliseconds? In that case you have even more work to do since rdtsc usually returns processor clock cycles with no simple relationship to wall clock time (given modern processors with dynamically adjusting clock frequencies). – mattnewport Aug 25 '15 at 20:45
  • @Patrick87 convert the value from uint64 to double – Naveen Aug 25 '15 at 20:52

3 Answers3

3

First of all, a uint64_t is not inherently hexadecimal, octal, nor decimal: It is simply a value. Unless, perhaps, there is some other encoding of its 64-bit value?

The range of uint64_t cannot exceed the range of a double, but there could well be some loss of precision during the conversion. This stems from the internal representation of a double which uses a total of 64 bits: 1 bit for the sign, 11 for the exponent, and 53-54 for the mantissa. In contrast, a uint64_t uses 64 bits for the value.

Nearby timestamps are likely to have the same double value. So subtracting one from the other would provide a difference as uint64, but zero as a double.

The usual method to convert from one to the other in c works great in c++ too:

uint64_t val64 = 892749724729742uL;
double d = val64;
wallyk
  • 56,922
  • 16
  • 83
  • 148
  • Depending on compiler and warning levels you may get a warning about possible loss of data without an explicit cast (`static_cast` or C-style cast) from `uint64_t` to `double` – mattnewport Aug 25 '15 at 20:34
0

use static_cast

double val = static_cast<double>(executionTime);

reinterpret_cast say 'those there bits are really a double', but they are not.

pm100
  • 48,078
  • 23
  • 82
  • 145
  • This gives an error, error: invalid static_cast from type ‘uint64_t [4] {aka long unsigned int [4]}’ to type ‘double’ – Naveen Aug 25 '15 at 20:09
  • 1
    @Naveen: that error implies that `executionTime` is an array of 4 `uint64_t` values, rather than a single value. Which element of the array to you want to convert? – Chris Dodd Aug 25 '15 at 20:15
  • which doesnt match his sample either :-( – pm100 Aug 25 '15 at 20:17
  • Oh yes, I overlooked the array part. Apparently they are different metrics like single, average, min/max execution times. But, does static cast convert the value from hex to double in this case or just represents hex in double format? static cast applied to a profiler out of 0x9f0340 gives a value of 1000. – Naveen Aug 25 '15 at 20:24
  • `static_cast` just converts an unsigned integer into a double with the same value (assuming it is representable). For example, `static_cast(10u)` gives a double with the value 10.0. – mattnewport Aug 25 '15 at 20:26
  • @mattnewport Turns out that's what he wants. Looks like our answers weren't what he was going for. – Patrick87 Aug 25 '15 at 20:55
  • problem is - we dont know what he actually has as starting point. Hasnt posted any real code – pm100 Aug 25 '15 at 20:55
-2

Assuming you are trying to reinterpret the bits as a double, the fully safe, portable way to do this in C++ is to use memcpy:

uint64_t executionTime = profilerObj.getTime; //for example 0x9f0340
double executionTimeAsDouble = 0.0;
memcpy(&executionTimeAsDouble, &executionTime, sizeof(executionTimeAsDouble);
cout << "Execution time is : " << executionTimeAsDouble;
mattnewport
  • 13,728
  • 2
  • 35
  • 39
  • thats going to give the same answer as reinterpet_cast – pm100 Aug 25 '15 at 20:08
  • @pm100 No, he's using `reinterpret_cast` wrong if that's what he is trying to accomplish, and even if he was using it 'correctly' it would still be unsafe / undefined behavior. – mattnewport Aug 25 '15 at 20:09
  • it works but it does the same as reinterpret cast. He doesnt want that, he wants to get a long into a double – pm100 Aug 25 '15 at 20:16
  • @pm100 If he actually wants to reinterpret the bits of the `uint64_t` as a `double` he should have had `*reinterpret_cast(&executionTime)` not `reinterpret_cast(executionTime)` as was originally in the question. The result of that cast is undefined however and may not work if compiling with strict aliasing, if that's what is wanted then `memcpy()` is the way to go. – mattnewport Aug 25 '15 at 20:21
  • you are right reinterpret_Cast needs pointers. But I still think he wants to take the output of a function that returns a long long and make it into a double, A nice old fashioned cast will do the trick – pm100 Aug 25 '15 at 20:26