Thread: Double's and floats, i need their bytes.

  1. #16
    Registered User
    Join Date
    Jul 2008
    Posts
    38
    I have adapted the above code in to this:

    Code:
    bool isOSBigEndian()
    {
    	short check = 0xAABB;
    	
    	uint8_t* endianCheck = reinterpret_cast<uint8_t*>(&check);
    	return (endianCheck[0] == 0xAA && endianCheck[1] == 0xBB);
    }
    
    uint8_t* convertDoubleToBytes(double value)
    {
    	uint8_t* bytes = reinterpret_cast<uint8_t*>(&value);
    	if (isOSBigEndian())
    	{
    		uint8_t* swappedBytes = new uint8_t[sizeof(double)];
    		for (int i = 0, j = 7; i <= 7 && j >= 0; i++, j--)
    		{
    			swappedBytes[i] = bytes[j];
    		}
    		return swappedBytes;
    	}
    	else
    	{
    		return bytes;
    	}
    }
    The check for endiannes works on both platforms. I get false on X86 and true on PPC.

    But the bytes i get from the convertDoubleToBytes function are like garbage when compared to those from an union. The numbers don't change between different executions of the program.

    From function:
    Code:
    154, 159, 4, 8, 95, 140, 4, 8
    From union:
    Code:
    154, 153, 153, 153, 153, 25, 73, 64
    The test was done on a X86 machine.

    I thought maybe the function was correct in some sort of odd way, so i tried to convert it back to a double using the following:

    Code:
    double* value = reinterpret_cast<double*>(bytes);
    and (probably very wrong)

    Code:
    double* value = (double*)((void*)bytes);
    Both returned this value:

    Code:
    4.86187e-270
    I can't think of any solution, and neither what the problem could be.

  2. #17
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Code:
    for (int i = 0, j = 7; i <= 7 && j >= 0; i++, j--)
    Note that you don't need j; j is just, after all, 7-i.

    Also, you could use sizeof(double) instead of hard-coding 7 (8-1).
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #18
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    This was just a quick example.
    I'm working on a generic solution right now.

    UPDATE:
    I think this generic swap should work:
    Code:
    template<typename T> void ByteSwap(T& Data)
    {
    	T Temp = Data;
    	uint8_t* pData = reinterpret_cast<uint8_t*>(&Data);
    	uint8_t* pTemp = reinterpret_cast<uint8_t*>(&Temp);
    	for (int i = 0; i < sizeof(Data); i++)
    		pData[i] = pTemp[(sizeof(Data) - 1) - i];
    }
    I tested it and it works fine in swapping byte order.
    Last edited by Elysia; 07-04-2008 at 04:21 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #19
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Quote Originally Posted by dwks View Post
    Code:
    for (int i = 0, j = 7; i <= 7 && j >= 0; i++, j--)
    Note that you don't need j; j is just, after all, 7-i.
    What would be the advantage of using 7-i over j?

  5. #20
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    One less variable, and it's the common idiom for sequence reversal.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #21
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Quote Originally Posted by CornedBee View Post
    One less variable, and it's the common idiom for sequence reversal.
    Yes one less variable in C++, but the compiler will need a temp for 7-i.
    Last edited by swoopy; 07-06-2008 at 03:31 AM.

  7. #22
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Yes, but in this case I'm talking about the readability of the code, not the efficiency. Keeping track of the values of a second variable is harder than knowing that END-i is always the opposite position.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #23
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    So you find this more readable?
    Code:
    		for (int i = 0; i <= 7 && 7-i >= 0; i++)
    		{
    			swappedBytes[i] = bytes[7-i];
    		}
    I'm not disagreeing, but neither seems particularly difficult to read.

  9. #24
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I find this even more readable:
    Code:
    for (int i = 0; i < 8; i++)
    {
    	swappedBytes[i] = bytes[7-i];
    }
    Given i <= 7 (but I prefer i < 8), 7-i >= 0 is a tautology. It's a useless condition. So now we're down to a very simple for-loop header, which I take over the two variables any day.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #25
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >So now we're down to a very simple for-loop header, which I take over the two variables any day.
    Well I guess we'll just have to agree to disagree.

  11. #26
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Yes, some readability issues are a matter of taste.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  12. #27
    Registered User
    Join Date
    Jul 2008
    Posts
    38
    After some fiddling around with the new swapping code you graciously came up with, i noticed something odd. When i changed the value of the double i was converting to bytes, i saw that only one value of the bytes changed, and the rest stayed the same.

    So i thought it might not be the function converting the double in to bytes that is at fault, but maybe the code printing the byte array was at fault.

    So i glanced over the code that printed out the bytes, and i could not find anything. To quickly overcome any headaches searching for the fault in this piece code that was never going to be used again (it was temporary code), i conjured up this:

    Code:
        bool same = true;
        for (int i = 0; i < sizeof(double); i++)
        {
    	if (bytes[i] != d_u.data[i])
    	{
    	    same = false;
    	    break;
    	}
        }
        std::cout << (same ? "Same" : "Not the same") << "\n";
    This piece code checked if the byte arrays of the conversion, and that of an union, was the same (i was using a X86 machine). And they were. So it must be the code that printed out the byte array that is at fault.

    I will 'try' to fix the bug in the code printing the byte array myself, since its unrelated to this topic. But if i can't, i will be certain to flee back to here .

    Here is the piece of code that eventually did the job:

    Code:
    bool isOSBigEndian()
    {
    	short check = 0xAABB;
    	
    	uint8_t* endianCheck = reinterpret_cast<uint8_t*>(&check);
    	return (endianCheck[0] == 0xAA && endianCheck[1] == 0xBB);
    }
    
    template<typename T> void ByteSwap(T& Data)
    {
    	T Temp = Data;
    	uint8_t* pData = reinterpret_cast<uint8_t*>(&Data);
    	uint8_t* pTemp = reinterpret_cast<uint8_t*>(&Temp);
    	for (int i = 0; i < sizeof(Data); i++)
    		pData[i] = pTemp[(sizeof(Data) - 1) - i];
    }
    
    uint8_t* convertDoubleToBytes(double value)
    {
    	if (isOSBigEndian())
    	{
    		ByteSwap<double>(value);
    		uint8_t* bytes = reinterpret_cast<uint8_t*>(&value);
    		return bytes;
    	}
    	else
    	{
    		uint8_t* bytes = reinterpret_cast<uint8_t*>(&value);
    		return bytes;
    	}
    }
    Thanks for all your help

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. New programmer missing somthing -- help!
    By jimmy the saint in forum C Programming
    Replies: 20
    Last Post: 02-23-2008, 05:57 PM
  2. a few opengl(or general programming) questions
    By linuxdude in forum Game Programming
    Replies: 20
    Last Post: 06-14-2004, 07:47 AM
  3. floats and doubles
    By volk in forum C++ Programming
    Replies: 2
    Last Post: 03-31-2003, 04:53 PM
  4. rewritten scanf for floats
    By monkey_C in forum C Programming
    Replies: 3
    Last Post: 12-09-2002, 04:21 PM