64 bit problem
Hello,
I recieved 8 bytes of data via socket byte stream and I stored the data in a byte array of unsigned char. I need to place each of these bytes in a long double (8 bytes) in the same order they are in the byte array. The 64 bit float will be using ANSI/IEEE Std 754 format to interpret the value. Ordinarly this would be easy as I could just set up a 8 bit mask and set each byte in the 32 bit value accordingly. However, since it is a 64 bit value, it is not allowing me to do any bit manipulation for some reason. I'm using GCC version 3.8 so I'm not sure if this is an issue. I also tried to set a long double pointer to point towards the first index of the byte array, hoping it would take in the whole 64 bits but it did not work for some reason (possibly my casting was wrong). I feel I'm on the right track but I just can't gather a solution. I hope I am being clear enough? Does anyone have any ideas of how I could get my 64 bit float value out of the 8 bytes in the byte array. Thanks for the help.
If the data in the array is in fact a 64bit float (double), and stored in the correct byte order, you should be able to just access it as if it was a double (after all, it's just raw binary data).
What probably went wrong in your cast approach, was that you cast to a long double, which is the extended ieee floating point representation - 80bits long.
What probably went wrong in your cast approach, was that you cast to a long double, which is the extended ieee floating point representation - 80bits long.
Your bytes might be reversed (big-endian/little-endian difference). But I would expect one of these pieces of code to work, depending on if you need to reverse the bytes or not:
This is probably somewhat crappy code, but it should get the job done. At least gets the idea across.
double ToDouble_NoSwap(unsigned char* ByteArray){ double n; unsigned char* p = (unsigned char*)&n; for (int i = 0; i < 8; ++i) p = ByteArray; return n; //Or could just use this code: //return *((double*)ByteArray);}double ToDouble_WithSwap(unsigned char* ByteArray){ double n; unsigned char* p = (unsigned char*)&n; for (int i = 0; i < 8; ++i) p = ByteArray[7 - i]; return n;}
This is probably somewhat crappy code, but it should get the job done. At least gets the idea across.
Apparently I was using a long double previously which turns out to be 16 bytes and the extended IEEE format; so that was no good.
I tried both the union and the sample code posted and I get the same answer for both but not the answer I think I should be getting. For example: the floating point 17.5 would equal (in 64 bit IEEE form)
Sign: 0
Exponent: 10000000011 // 4
Mantissa: 000110000000000.... // 10001.1 normalized
Using these values, I just made a byte array with test data to see if it would output the right value.
Output:
The value of n is: 1076985856
Does the code work correctly or is it just my test data that is wrong? Thanks again for the help.
I tried both the union and the sample code posted and I get the same answer for both but not the answer I think I should be getting. For example: the floating point 17.5 would equal (in 64 bit IEEE form)
Sign: 0
Exponent: 10000000011 // 4
Mantissa: 000110000000000.... // 10001.1 normalized
Using these values, I just made a byte array with test data to see if it would output the right value.
#include <stdio.h>int main(){ int i; unsigned char buffer[256]; buffer[0] = 64; buffer[1] = 49; buffer[2] = 128; buffer[3] = 0; buffer[4] = 0; buffer[5] = 0; buffer[6] = 0; buffer[7] = 0; unsigned char* ByteArray = &buffer[0]; double n; unsigned char* p = (unsigned char*)&n; for(i=0; i < 8; ++i) p = ByteArray; printf("The value of n is: %d\n", n); return 0;}
Output:
The value of n is: 1076985856
Does the code work correctly or is it just my test data that is wrong? Thanks again for the help.
If your system is little endian, the lowest byte is stored first.
So you may turn around the bytes:
Result is:
So you may turn around the bytes:
#include <iostream>using namespace std; int main(){ double d; unsigned char* buffer = (unsigned char*)&d; buffer[0] = 0; buffer[1] = 0; buffer[2] = 0; buffer[3] = 0; buffer[4] = 0; buffer[5] = 0x80; buffer[6] = 0x31; buffer[7] = 0x40; cout << "d: " << d << endl; return 0;}
Result is:
d: 17.5
Very strange, when I use the C++ version (using cout and g++ compiler) I get 17.5, but when I use the C version (with printf and gcc compiler) it gives me the 1076985856 number. But at least I know it is being interpretted right (the C++ version shows that). Anyone have any ideas why I am not getting the right answer with C?
Quote:Original post by ElwrenAre you using the correct formatting code with printf?
Very strange, when I use the C++ version (using cout and g++ compiler) I get 17.5, but when I use the C version (with printf and gcc compiler) it gives me the 1076985856 number. But at least I know it is being interpretted right (the C++ version shows that). Anyone have any ideas why I am not getting the right answer with C?
I'm using printf("%d", nameOfDouble);
I tried adding the modifer printf("%ld", nameofDouble); as well but it gave the same result. That is correct right?
I tried adding the modifer printf("%ld", nameofDouble); as well but it gave the same result. That is correct right?
Quote:Original post by ElwrenNo. %d is to print a decimal integer value. You need to use %e, %E, %f, %F, %g, or %G.
I'm using printf("%d", nameOfDouble);
I tried adding the modifer printf("%ld", nameofDouble); as well but it gave the same result. That is correct right?
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement