CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Jan 2002
    Posts
    2

    Convert float to Big Endian

    Hi.

    I want to read a binary file with a big endian sequence. I can convert int, short and long by simply changin bit order. However, I can not convert float & double to Big Endian Sequence. Could you please let me know the method?

    Thank you.


  2. #2
    Join Date
    Nov 2000
    Location
    Reston, Virginia, USA
    Posts
    466

    Re: Convert float to Big Endian

    Files even "binary" files are stored in characters. That means when you write a string to a binary file you're actually writing a character string. Characters are only byte values so no need to worry about big Endian etc.
    Check it out..

    The big Endian, little Endian issue really comes into play when you're transfering data over a socket between OS's

    Transfering datafiles between OS's usually ammounts to handling the end of line and line feeds characters correctly.


  3. #3
    Join Date
    Dec 2001
    Location
    GERMANY
    Posts
    198

    Re: Convert float to Big Endian

    Hello,
    I am a bit confused about your claim that "even binary files are stored in characters" and that you don't have to worry about big Endian, etc. This is in my opinion not correct. Binary files can maintain the memory characterstics of the machine which created it, depending on how the binary file was create. I submit an example program and the output as viewed by a hex editor. This is certainly not a string.

    If I misunderstood your explanation, please give a more thorough explanation of how you create the binary files you are talking about, as this has nothing in common with the binary files I use to store binary data.

    Best regards.

    The output in a hex editor:
    00 00 80 3F 00 00 80 BF 60 E5 CF 41




    The test program:


    int main(int argc, char* argv[])
    {
    float f1;
    FILE* pTestFile= 0;
    printf("Writing float to the file testfloat.bin\n");
    f1 = 25.987;
    pTestFile = fopen("testfloat.bin", "w+b");
    if (pTestFile == NULL)
    return -1;
    f1 = 1.00;
    fwrite(&f1, sizeof(float), 1, pTestFile);
    f1 = -1.00;
    fwrite(&f1, sizeof(float), 1, pTestFile);
    f1 = 25.987;
    fwrite(&f1, sizeof(float), 1, pTestFile);
    fclose(pTestFile);
    return 0;
    }






    Please rate my answer, whether good or bad, so I can improve the answers I give. Thanks!

  4. #4
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Convert float to Big Endian

    A float and a double are actually stored as bit-maps. float is 32 bit and double is 64 bit and there is a long double which I think is 128 bit.

    I think it is standard on all systems.


    The best things come to those who rate

  5. #5
    Join Date
    Dec 2001
    Location
    GERMANY
    Posts
    198

    Re: Convert float to Big Endian

    A modified version of my previous program shows that writing the binary format of the float to a file (using fwrite()) uses the machine's byte ordering scheme.

    Here's the new test program (run on an Intel machine):

    int main(int argc, char* argv[])
    {
    float f1;
    unsigned int* pInt1;
    unsigned char msb1, msb2, msb3, msb4;
    FILE* pTestFile= 0;
    printf("Writing float to the file testfloat.bin\n");
    f1 = 25.987;
    pTestFile = fopen("testfloat.bin", "w+b");
    if (pTestFile == NULL)
    return -1;

    f1 = 25.987;
    pInt1 = (unsigned int*) &f1;
    msb1 = (unsigned char) ((*pInt1) >> 24);
    msb2 = (unsigned char) ((*pInt1) >> 16);
    msb3 = (unsigned char) ((*pInt1) >> 8);
    msb4 = (unsigned char) ((*pInt1) & 0x000000FF);

    fwrite(&f1, sizeof(float), 1, pTestFile);
    fwrite(&msb1, 1, 1, pTestFile); // Most significant byte
    fwrite(&msb2, 1, 1, pTestFile);
    fwrite(&msb3, 1, 1, pTestFile);
    fwrite(&msb4, 1, 1, pTestFile); // Least significant byte
    fclose(pTestFile);
    return 0;
    }






    The hex contents of the file:
    60 E5 CF 41 41 CF E5 60

    which shows that the float is stored with little-endian byte ordering when the float is supplied as a parameter to fwrite(), but when outputting the single bytes from most significant to least signficant we see the reverse order (like it would be with big-endian).

    It would be interesting to see the same program run on a mac or some other machine whose processor uses big-endian byte ordering.

    Let me know if I'm getting this completely wrong, but I think that all the issues involved with sending binary data over a socket connection apply just as well to files. They are, after all, both simply serialized forms of the data.

    Regards.




    Please rate my answer, whether good or bad, so I can improve the answers I give. Thanks!

  6. #6
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Convert float to Big Endian

    this program would give different results on a big-endian machine, not because of the way it outputs float, but because you cast to unsigned int * and then looked at the results.

    So on an LSB 60 E5 CF 41 is one integer and on an MSB it is another.

    All you have proved is that Windows is LSB. And it's the operating system, not the processor, that determines the order.



    The best things come to those who rate

  7. #7
    Join Date
    Dec 2001
    Location
    GERMANY
    Posts
    198

    Re: Convert float to Big Endian

    Here's what MSDN says about little-endian byte ordering. There's no mention that Windows handles the byte ordering. Are we even talking about the same thing?
    Regards.

    -------------------
    little-endian
    Refers to a processor memory architecture in which the byte layout is as follows:

    · Byte N is the least significant (and, in conventional layout diagrams, the "rightmost") byte of:

    · A word composed of bytes N and (N + 1).

    · A double word composed of bytes N, (N + 1), (N + 2), and (N + 3).

    · A K-byte memory entity composed of bytes N, (N + 1),...,(N + K - 1).

    The address of the preceding word, double word, or K-byte entity is its least significant byte, N.

    Intel microprocessors always support little-endian addressing. Some RISC microprocessors can be configured for either big-endian or little-endian addressing. For a little-endian configuration, the least significant bit of a 16-bit short value is the "rightmost" bit at byte N, while the most significant bit is the "leftmost" bit of byte (N + 1). See also big-endian.



    Please rate my answer, whether good or bad, so I can improve the answers I give. Thanks!

  8. #8
    Join Date
    Nov 2000
    Location
    Reston, Virginia, USA
    Posts
    466

    Not how it was Created but how it was Written..

    >> This is in my opinion not correct. Binary
    >> files can maintain the memory characterstics
    >> of the machine which created it, depending on
    >> how the binary file was create

    It doesn't matter if the file is a binary file or a text file. You're example has the properties of the processor because that is what fwrite does..It dumps the contents of memory to a file unformated. The binary parameter on the fopen only influences the <CR> or <CR><LF>.

    To illistrate my point we can write two files an asscii one and a text one..


    int main(int argc, char* argv[])
    {
    int iVal =100;
    float fVal =9.8;
    char *pszBuffer = "100 - 9.8";
    FILE *stream;

    // write the binary file

    if( (stream = fopen( "BinData.txt", "w+b" )) == NULL )
    {
    printf( "The file 'data' was not opened\n" );
    return 0;
    }
    else
    {
    printf( "The file 'data' was opened\n" );
    }

    fwrite( &iVal, sizeof( int ), 1, stream );

    fprintf( stream, "\n%d - %3.1f\n", iVal, fVal );
    fprintf( stream, "%s\n", pszBuffer );

    fclose ( stream );

    // write the ascii text file

    if( (stream = fopen( "TxtData.txt", "w+t" )) == NULL )
    {
    printf( "The file 'data' was not opened\n" );
    return 0;
    }
    else
    {
    printf( "The file 'data' was opened\n" );
    }

    fwrite( &iVal, sizeof( int ), 1, stream );
    fprintf( stream, "\n%d - %3.1f\n", iVal, fVal );
    fprintf( stream, "%s\n", pszBuffer );

    fclose ( stream );
    return 0;

    }




    The output from the BinData.txt file

    64 00 00 00 0A 31 30 30 20 2D 20 39 2E 38 0A 31 // <-- d....100 - 9.8.1
    30 30 20 2D 20 39 2E 38 0A // <- 00 - 98.




    The output from the TxtData.txt file

    64 00 00 00 0D 0A 31 30 30 20 2D 20 39 2E 38 0D // <- d.....100 - 9.8.
    0A 31 30 30 20 2D 20 39 // <- .100-9.8..




    The only difference between the binary file and the assci file being in the <CR> or the <LF>. That was my point..

    Now which I think was your point.. if you run the same program on a Solaris box.. which I did.. you will see that the fwrite command does memory dump the int value with the sig digs reversed..

    00 00 00 64




    But even here for both the binary and ascii files the other bytes remain constant across the platforms and this is because fprintf/cout etc etc.. writes characters to the file and not binary dumps like fwrite. Once again regardless of if the file was "created" with a binary flag or not... and regardless if the file was created on Solaris or NT.



  9. #9
    Join Date
    Dec 2000
    Location
    Norway
    Posts
    13

    Re: Convert float to Big Endian

    Another way of writing as big endian on a little endian machine (Intel):



    union FloatBytes {
    float FloatValue;
    unsigned char Byte[sizeof(float)];
    };

    FloatBytes f1;
    FILE* pTestFile = 0;
    int i;

    f1.FloatValue = (float) 25.987;

    //--- open file
    pTestFile = fopen("testfloat.bin", "w+b");
    if(!pTestFile) return -1;

    //--- write the little endian way..
    for(i=0; i<sizeof(float); i++) fwrite(&f1.Byte[i], 1, 1, pTestFile);

    //--- write the big endian way..
    for(i=sizeof(float)-1; i>=0; i--) fwrite(&f1.Byte[i], 1, 1, pTestFile);

    //--- close file
    fclose(pTestFile);





    Regards,
    Kjetil Haga


  10. #10
    Join Date
    Aug 2001
    Location
    MN, USA
    Posts
    177

    Re: Convert float to Big Endian

    f1 = 25.987;
    pInt1 = (unsigned int*) &f1;
    msb1 = (unsigned char) ((*pInt1) >> 24);
    msb2 = (unsigned char) ((*pInt1) >> 16);
    msb3 = (unsigned char) ((*pInt1) >> 8);
    msb4 = (unsigned char) ((*pInt1) & 0x000000FF);

    --------------------------

    Hi .. thanks so much for this codes. It helps me a lot in developing my project.
    However, I have another question if you can help me which is after a floating point number is converted to an four bytes of unsigned char. How do you reverse to process to read back its floating point number?
    Thanks in advance ..

    Michael





Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured