问题
I have a double converted to a unsigned char array. For example for value 1, the array becomes {64, 240, 0, 0, 0, 0, 0, 0}. Now I tried to convert the array back by using the following code, but all I got was crapy values...
double* pdfOutput = (double*)malloc(sizeof(double));
memcpy(pdfOutput, pInputArray, sizeof(double));
Would you please let me know where the problem is? Thanks.
Edit: The pInputArray is generated by LabVIEW. Basically what I am trying to do here is to make a program talking with a LabVIEW VI. So I don't have the control of the input array...
回答1:
The simple way to do what you ask is to write:
double pdfOutput = *(double*)pInputArray;
but this will yield just the same results as your code. In other words, reinterpreting the char array that you have does not result in the double value that you expect. You need to look into the source of the char array. The code that is creating the char array is where I would expect the problem to be. To solve your problem you need to understand what the LabVIEW code is doing.
回答2:
The problem is the order of the bytes (i.e. endianness). You may not be able to simply use memcpy(), depending on the endianness of your system. Regardless, if you're dealing with individual bytes, you'll have to take endianness into account... what will work on one system will not necessarily work on another.
Try this program:
#include <stdio.h>
//typedef __int64 int64; // for Visual Studio
//typedef unsigned __int64 uint64; // for Visual Studio
typedef long long int64; // for GCC
typedef unsigned long long uint64; // for GCC
//#define PRId64 "%I64d" // for Visual Studio
//#define PRIu64 "%I64u" // for Visual Studio
#define PRIu64 "%llu" // for GCC
#define PRId64 "%lld" // for GCC
union U {
unsigned char c[8];
int64 s64;
uint64 u64;
double d;
};
void printU( U& u )
{
printf("Raw bytes: %02x %02x %02x %02x %02x %02x %02x %02x "
" (%u %u %u %u %u %u %u %u)\n"
"Interpreted as a signed 64-bit integer: "PRId64"\n"
"Interpreted as an unsigned 64-bit integer: "PRIu64"\n"
"Interpreted as a double (with 'float' precision): %f\n\n",
u.c[0], u.c[1], u.c[2], u.c[3],
u.c[4], u.c[5], u.c[6], u.c[7],
u.c[0], u.c[1], u.c[2], u.c[3],
u.c[4], u.c[5], u.c[6], u.c[7],
u.s64, u.u64, (float)u.d);
}
int main()
{
U u;
u.c[0]=63; u.c[1]=240; u.c[2]=0; u.c[3]=0;
u.c[4]=0; u.c[5]=0; u.c[6]=0; u.c[7]=0;
printU(u);
u.c[0]=0; u.c[1]=0; u.c[2]=0; u.c[3]=0;
u.c[4]=0; u.c[5]=0; u.c[6]=240; u.c[7]=63;
printU(u);
}
On my x86 Linux system with GCC, I get the following results:
Raw bytes: 3f f0 00 00 00 00 00 00 (63 240 0 0 0 0 0 0) Interpreted as a signed 64-bit integer: 61503 Interpreted as an unsigned 64-bit integer: 61503 Interpreted as a double (with 'float' precision): 0.000000 Raw bytes: 00 00 00 00 00 00 f0 3f (0 0 0 0 0 0 240 63) Interpreted as a signed 64-bit integer: 4607182418800017408 Interpreted as an unsigned 64-bit integer: 4607182418800017408 Interpreted as a double (with 'float' precision): 1.000000
I suspect someone running Visual Studio (on x86 of course) would get the same results. When I run the same program on a PowerPC Linux machine (also GCC), I get these results:
Raw bytes: 3f f0 00 00 00 00 00 00 (63 240 0 0 0 0 0 0) Interpreted as a signed 64-bit integer: 4607182418800017408 Interpreted as an unsigned 64-bit integer: 4607182418800017408 Interpreted as a double (with 'float' precision): 1.000000 Raw bytes: 00 00 00 00 00 00 f0 3f (0 0 0 0 0 0 240 63) Interpreted as a signed 64-bit integer: 61503 Interpreted as an unsigned 64-bit integer: 61503 Interpreted as a double (with 'float' precision): 0.000000
I'm making the assumption that you can convert this research into the appropriate conversion code for your platform. If my assumption is incorrect, let me know & I'll write the 2-line code you need for you after you run the above program on your system & post the results.
来源:https://stackoverflow.com/questions/9812155/convert-from-unsigned-char-array-to-double