Jump to content
  • Advertisement
Sign in to follow this  

64 bit problem

This topic is 4747 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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:

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.

Share this post


Link to post
Share on other sites
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.


#include &lt;stdio.h&gt;
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 &lt; 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.

Share this post


Link to post
Share on other sites
If your system is little endian, the lowest byte is stored first.
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

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Quote:
Original post by Elwren
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?
Are you using the correct formatting code with printf?

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Quote:
Original post by Elwren
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?
No. %d is to print a decimal integer value. You need to use %e, %E, %f, %F, %g, or %G.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!