This question already has an answer here:
I am facing some problem with converting 8 bytes to a double. I have following byte array
0x98 0xf9 0x38 0x4e 0x3a 0x9f 0x1c 0x43
And I am trying to do following
for (int i = 1; i < 8; i++)
mult[i] = 256 * mult[i - 1];
double out= buf[7] * mult[7] + buf[6] * mult[6] + buf[5] * mult[5] + buf[4] * mult[4] + buf[3] * mult[3] + buf[2] * mult[2] + buf[1] * mult[1] + buf[0] * mult[0];
But it is not giving the correct answer. I am getting out is equal to 4835915172658346392 and actual value is 2014093029293670.
Note: *((double *) (buf))
works fine but I don't think it would be compiler and OS safe.
Edit:
long mult[8];
I start with mult[0]=1
Try this:
or
or
In C++:
In C++11, you can also use std::begin(buf) and std::end(buf) as the boundaries (include the header ), and in both languages you can use sizeof(buf) / sizeof(buf[0]) (or simply sizeof(buf)) for the size, all provided buf is actually an array and not just a pointer.
Note that your code could be written more elegantly:
In this way you can see more clearly where is error!
You say that
0x98 0xf9 0x38 0x4e 0x3a 0x9f 0x1c 0x43
is supposed to represent2014093029293670
.This is true if the former is the little-endian representation of that integer in IEEE754 binary64 format. So your approach by using byte-by-byte multiplication (or equivalently, bit shifts) is not going to work, because those are arithmetic operations.
Instead you need to alias that representation as a
double
. To do this portably, on a little-endian machine on whichdouble
is IEEE754 binary64:If you want this code to work on a machine with different endianness then you will need to rearrange
buf
before doing thememcpy
. (This is assuming that the representation is always obtained in little-endian format, which you didn't state).