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

  1. #1
    Registered User
    Join Date
    Jul 2008
    Posts
    38

    Double's and floats, i need their bytes.

    Hello everybody,

    I need the actual bytes of a double and a float, i tried to use bitwise operators but this was not possible (Compiler says no, probably for a good reason?). Unions work great on floats and double's, but the problem is (besides that unions are bit frowned upon in this case, i believe?) the resulting bytes will eventually be send over a network connection, and may go from a X86 computer to a PPC machine (or vice versa). Using bitwise operators on an int or short is no problem on both platforms, since they provide the same result. But when i use an union on a double and on a float the result is different.

    So i have been pondering over a solution. I even tried casting the double to a long int and tried using bitwise operators on them, but that failed.

    So, how do i get the actual bytes of a double and of a float?

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    double d = 1.0;
    const uin8_t* p = (uint8_t*)&d;
    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.

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Use unsigned char* instead of uin8_t*, since a char is guaranteed to be one byte. Use reinterpret_cast instead of a C style cast.
    Code:
    double d = 1.0;
    const unsigned char* p = reinterpret_cast<unsigned char*>(&d);
    Your bytes will be from p to p + sizeof(double).

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Ah, yes, this is C++.
    uint8_t is guaranteed to be 1 byte. Otherwise there's something wrong with your stdint.h header.
    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.

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    uint8_t is not standard in C++.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Regardless, it is something it needs. A stdint.h header is available to acquire on the web.
    (I always use them.)
    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.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Regardless, it is something it needs. A stdint.h header is available to acquire on the web.
    This is irrelevant. char is standard and works. You don't just download headers off the web to include in your standard library, especially not to solve a problem that already has a solution.

  8. #8
    Registered User
    Join Date
    Jul 2008
    Posts
    38
    Thank you all for your replies.

    I have successfully been able to use this code to get the bytes:

    Code:
    const uint8_t* bytes2 = reinterpret_cast<uint8_t*>(&value);
    This returns the following array of bytes on a X86 computer (If the number was 50.2):

    Code:
    154, 153, 153, 153, 153, 25, 73, 64
    But on a PPC computer it's:

    Code:
    64, 73, 25, 153, 153, 153, 153, 154
    Is there a way the get same results on both platforms?

    The OS is Linux on both platforms.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Daved View Post
    >> Regardless, it is something it needs. A stdint.h header is available to acquire on the web.
    This is irrelevant. char is standard and works. You don't just download headers off the web to include in your standard library, especially not to solve a problem that already has a solution.
    Why are you so negative?
    It's a great header that allows for the use of fixed-size width variables, something missing from C++.

    Quote Originally Posted by Florian View Post
    Is there a way the get same results on both platforms?
    The OS is Linux on both platforms.
    Unfortunately, this is due to how hardware works.
    Intel is low endian and powerpc is high endian.

    The solution, then, would be to check for what endianess the processor is and if isn't, say, low endian, then byte swap the data.

    Such an approach may look like (this will swap high endian to low endian):
    Code:
    uint16_t EndianCheck = 0x1234;
    uint8_t* pEndianCheck = reinterpret_cast<uint8_t*>&EndianCheck;
    bool bNeedSwap = (pEndianCheck[0] == 0x12 && pEndianCheck[1] == 0x34);
    
    double Data = 1.0;
    uint8_t* pData = reinterpret_cast<uint8_t*>(&Data);
    if (bSwap)
    {
        double Temp;
        uint8_t* pTemp = reinterpret_cast<uint8_t*>(&Temp);
        for (int i = 0, j = 7; i <= 7 && j >= 0; i++, j--)
            pTemp[i] = pData[j];
        Data = Temp;
    }
    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.

  10. #10
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Are floating point numbers affected by Endiness? I've only heard of htonl() or htons(), but not htonf()...

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by cpjust View Post
    Are floating point numbers affected by Endiness? I've only heard of htonl() or htons(), but not htonf()...
    Yes they are. Every built-in data type larger than one byte is.
    The reason you don't get something like htonf is that not all platforms use the same representation of floating point numbers anyway. You are lucky if endianness is the only difference between two floating point units. I don't believe there is a truly portable way to transfer floats between all platforms. The OP is simply using a hack that works in his case.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by iMalc View Post
    Yes they are. Every built-in data type larger than one byte is.
    The reason you don't get something like htonf is that not all platforms use the same representation of floating point numbers anyway. You are lucky if endianness is the only difference between two floating point units. I don't believe there is a truly portable way to transfer floats between all platforms. The OP is simply using a hack that works in his case.
    Well in that case, I'd say the only portable way to send floating point numbers is to convert them to strings like "3.1415" and convert them back to floats or doubles on the other end.

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Still not 100&#37; portable - if the target platform's float has worse precision than the source platform, you lose this precision. (Not that there is anything you can do about that.)

    Endianness curiosity: there are some ancient platforms where integers have one endianness and floats another.
    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

  14. #14
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Well if you take away all the obscure platforms and only talk about the mainstream ones like x86, Itanium, SPARC, and whatever AS/400 & z/OS uses, would those use compatible floating point numbers?

  15. #15
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I'm not quite sure if AS/400 uses IEEE-754 floats.
    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

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