How to convert a byte array into double in C?
Try this:
double a;
memcpy(&a, ptr, sizeof(double));
where ptr
is the pointer to your byte array. If you want to avoid copying use a union, e.g.
union {
double d;
char bytes[sizeof(double)];
} u;
// Store your data in u.bytes
// Use floating point number from u.d
converting byte array to double - c
Edit: this won't work (see comment) without something like __int128
.
a = input[i] << 8*i;
The expression input[i]
is promoted to int
(6.3.1.1) , which is 32bit on your machine. To overcome this issue, the lefthand operand has to be 64bit, like in
a = (1L * input[i]) << 8*i;
or
a = (long long unsigned) input[i] << 8*i;
and remember about endianness
Converting 8 bytes to double
You say that 0x98 0xf9 0x38 0x4e 0x3a 0x9f 0x1c 0x43
is supposed to represent 2014093029293670
.
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 which double
is IEEE754 binary64:
static_assert( sizeof(double) == 8 );
double out;
memcpy(&out, buf, sizeof out);
If you want this code to work on a machine with different endianness then you will need to rearrange buf
before doing the memcpy
. (This is assuming that the representation is always obtained in little-endian format, which you didn't state).
Convert 8 bytes to double value
You can use union, this works for me:
#include <iostream>
using namespace std;
int main() {
union { char b[8]; double d; };
b[7] = 0x3F;
b[6] = 0xD1;
b[5] = 0x9B;
b[4] = 0x94;
b[3] = 0xC0;
b[2] = 0x00;
b[1] = 0x00;
b[0] = 0x00;
cout << "Double: " << d << endl;
return 0;
}
Please note reverse order of bytes. It depends on endianness and can differ on your machine. Anyway it outputs:
Double: 0.275121
byte array to double conversion in c#
Well a double is an array of 8 bytes, so with 3 bytes you won't have all the possible values.
To do what you want:
var myBytes[] = {0,0,0,0,0,1,1,2}; //assume you pad your array with enough zeros to make it 8 bytes.
var myDouble = BitConverter.ToDouble(myBytes,0);
Convert between double and byte array, for transfer over ZigBee API?
What you're doing is called type punning.
Use a union:
union {
double d[2];
char b[sizeof(double) * 2];
};
Or use reinterpret_cast
:
char* b = reinterpret_cast<char*>(d);
How to convert a byte array of size 64 to a list of double values in Arduino C++?
I am not completly sure what you are trying to achieve here because of the code (sizeof(ch) / sizeof(*ch))
which does not make sense for an array of undefined size.
If you have a byte-Array (POD data type; something like a typedef char byte;
) then this most simple solution would be a reinterpret_cast:
double *result = reinterpret_cast<double*>(ch);
This allows you to use result[0]..result[7] as long as ch[]
is valid and contains at least 64 bytes. Be aware that this construct does not generate code. It tells the compiler that result[0] corresponds to ch[0..7] and so on. An access to result[] will result in an access to ch[].
But you have to know the number of elements in ch[]
to calculate the number of valid double elements in result
.
If you need a copy (because - for example - the ch[] is a temporary array) you could use
std::vector<double> result(reinterpret_cast<double*>(ch), reinterpret_cast<double*>(ch) + itemsInCh * sizeof(*ch) / sizeof(double));
So if ch[] is an array with 64 items and a byte is really an 8-bit value, then
std::vector<double> result(reinterpret_cast<double*>(ch), reinterpet_cast<double*>(ch) + 8);
will provide a std::vector
containing 8 double values.
There is another possible method using a union:
union ByteToDouble
{
byte b[64];
double d[8];
} byteToDouble;
the 8 double values will occupie the same memory as the 64 byte values. So you can write the byte values to byteToDouble.b[]
and read the resultingdouble values from byteToDouble.d[]
.
Convert char array to double using unions with all decimal places
Solution from the comments (higher precision) (faster code):
double getDouble(char array[]) {
double result;
memcpy(&result, array, sizeof(result));
return result;
}
int main(int argc, char *argv[]) {
char array[8] = {13, 67, -76, -39, -6, 59, -58, 63};
printf("%.17f", getDouble(array));
return 0;
}
This prints the Java-like "0.17370544080815656". I could even increase the precision.
Thanks to @user3121023 @ameyCU @Andrew Henle
Related Topics
Specifying Default Parameter When Calling C++ Function
Partial Specialization Ordering with Non-Deduced Context
Fastest Timing Resolution System
Generate N Random Numbers Within a Range with a Constant Sum
Reading Directly from an Std::Istream into an Std::String
How to Call a Cmake Function from Add_Custom_Target/Command
Factory Method Implementation - C++
What Does Exactly the Warning Mean About Hidden Symbol Being Referenced by Dso
Equivalent of Console.Readline() in C++
The Cxx Compiler Identification Is Unknown
How to Call the Class's Destructor
What's the Standard/Official Name for Universal References
How Is If Statement Evaluated in C++
Why Add Void to Method Parameter List
Any Good Reason Why Assignment Operator Isn't a Sequence Point