Thread: Converting Sign Magnitude Integer Binary Files

  1. #1
    Registered User
    Join Date
    Sep 2004
    Posts
    4

    Converting Sign Magnitude Integer Binary Files

    Hi All,

    I am having difficulty finding the right C code to convert a data file. I previously succeeded in converting this format using Python but to improve the speed and portability I now wish to code it in C and that is presenting me with problems.

    I have a binary data file which contains numerical data in Sign Magnitude Integer format (obsolete and annoying). Essentially this means there are two bytes of information per record, one determines the sign of the number and the other the magnitude. That is not the problem I am having really though. I do not know the built in ANSI C syntax for converting binary data to ascii format. Once that is done I will need to undo the SMI data and will be left with numbers with base 16 (hex) which I then need to convert to base 10 (decimal).

    The information I need is how to convert binary data to ascii data (in small segments of 1 or 2 bytes at a time)...and also if there is a builtin for ansi C which will convert from hex to decimal.

    I have been playing with sprintf but I am not sure if this is the way forward - it doesn't seem to be yielding the right answers so far anyway.

    Thanks guys!

    Arthur.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    There is no difference between "binary data" and "ascii data", other than if it falls into the ascii character set or not. A byte is a byte.
    Code:
    [signbyte][databyte][signbyte][databyte][signbyte][databyte]
    Is that what your file basicly looks like?
    Code:
    int c, signed = 1;
    while( c = fgetc( file ) != EOF )
    {
        if( signed )
        {
            ...figure out how you're handling your signed values, and why this matters...
        }
        else
        {
        }
        signed = !signed;
    }
    I'm not exactly sure why it matters if it's signed or not. If it's signed, does that mean in your case it isn't an ascii value? Or vice versa? Or what exactly? Again, there really isn't any difference. A byte is a byte. On Unix systems, there is no difference between binary files and ascii files, they're written exactly the same way. (This doesn't hold true under Windows, and likely other platforms, but read the man page for fopen and you'll see that they're treated exactly the same way.

    An example of what your output file is supposed to look like would make helping you a bit easier, even if you do it similar to my example above.

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Sep 2004
    Posts
    4
    Sign Magnitude means that the first bit of the high byte determines if the number is negative.

    The other 15 bits give the 'Magnitude' of the number.
    Examples:
    Byte1 Byte2
    0 0 = 0
    4 7 4*256 + 7 = 1031
    127 255 127*256 + 255 = 32767
    128 1 - (0*256 + 1) = -1 meter
    134 108 - [ (134-128)*256 + 108 ] = -1644
    255 255 - [ (255-128)*256 + 255 ] = -32767

    Note: 128,0 would give -0
    (This seems like a waste but thats the way it works)



    I am programming on windows but need the code to work on *nix as well.

    Essentially the difficulties I am having are:

    converting a binary string to a ascii string so that I can manipulate the numbers

    converting hexadecimal numbers to decimal numbers
    (could code the process myself but there must be a builtin somewhere!)

    thanks

    Arthur.

  4. #4
    Registered User
    Join Date
    Sep 2004
    Posts
    4
    Essentially the data format is obsolete, it was used on old IBM machines and some cray systems too. None of the data was ever supposed to be represented as ASCII so there are no ascii codes there.

    Its all numeric data which I need to manipulate - the final results need to be put out in ASCII though. But it is very difficult to debug the code (should that be necessary) if all the operations are done on binary data because then anaylsing the data streams to find the source of problems becomes a problem in itself.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Basically, sign-magnitude and 2's complement are the same for postitive integers
    For negative conversion, you do this

    Code:
    twos_complement = -( sign_magnitude & 0x7fff );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Apr 2004
    Posts
    210
    Maybe using Salem's solution like this...

    Code:
    unsigned short sign_magnitude;
    short twos_complement;
    
    if (sign_magnitude & 0x8000)
      twos_complement= -( sign_magnitude & 0x7fff );
    else
      twos_complement= sign_magnitude;

    you now have the two's complement that you can use it in functions like printf to represent it in different bases, i.e.

    Code:
    printf("Hex: %X, Decimal: %i\n", twos_complement, twos_complement);
    You can also use fprintf to dump this as human readable to a file. See also fopen, fclose, FILE.

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Arthur Dent
    I have a binary data file which contains numerical data in Sign Magnitude Integer format
    (obsolete and annoying). Essentially this means there are two bytes of information per record,
    one determines the sign of the number and the other the magnitude.
    Ah, I was under the impression you were saying "Byte one just says if it's signed, and the second byte..."

    Quote Originally Posted by Arthur Dent
    Sign Magnitude means that the first bit of the high byte determines if the number is negative.

    The other 15 bits give the 'Magnitude' of the number.
    Examples:
    Byte1 Byte2
    0 0 = 0
    4 7 4*256 + 7 = 1031
    127 255 127*256 + 255 = 32767
    128 1 - (0*256 + 1) = -1 meter
    134 108 - [ (134-128)*256 + 108 ] = -1644
    255 255 - [ (255-128)*256 + 255 ] = -32767
    First we build a test data file with some of your input:
    Code:
    #include <stdio.h>
    int main( void )
    {
            FILE *fp = fopen( "foo.bar", "wb" );
            fputc( 0  , fp ); fputc( 0  , fp );
            fputc( 4  , fp ); fputc( 7  , fp );
            fputc( 127, fp ); fputc( 255, fp );
            fputc( 128, fp ); fputc( 1  , fp );
            fputc( 134, fp ); fputc( 108, fp );
            fputc( 255, fp ); fputc( 255, fp );
            fclose( fp );
            return 0;
    }
    Then we do something like this:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    int main( void )
    {
            FILE *file;
            unsigned char bytes[2];
            signed short int number;
            char buf[BUFSIZ] = {0};
    
            file = fopen( "foo.bar", "rb" );
            if( file == NULL )
            {
                    exit( EXIT_FAILURE );
            }
            while( fread( bytes, sizeof bytes, 1, file ) == 1 )
            {
                    printf("%3u %3u read,  ", bytes[0], bytes[1] );
                    number = ((bytes[0] & 0x7F) << 8) + bytes[1];
                    number = bytes[0] & 128 ? 0 - number : number;
    
                    sprintf( buf, "%d", number );
                    printf("%s\n", buf );
            }
            return 0;
    }
    /*
    
      0   0 read,  0
      4   7 read,  1031
    127 255 read,  32767
    128   1 read,  -1
    134 108 read,  -1644
    255 255 read,  -32767
    
     */
    There's likely a better way to do it, but is that something along the lines of what you were looking for?

    [edit]
    Well son of a ... Beaten twice while I made a test program and made my post tidy.
    [/edit]

    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User
    Join Date
    Sep 2004
    Posts
    4

    Cool

    Thanks quzah - I have now solved the problem. I will probably post a code snippet of my solution later.

    Thanks everyone.

    Arthur.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Processing binary or plaintext files
    By Jags in forum C Programming
    Replies: 12
    Last Post: 08-04-2006, 02:35 PM
  2. Binary files
    By Lionmane in forum C Programming
    Replies: 35
    Last Post: 08-25-2005, 01:56 PM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  4. Linked Lists Integer addition ? HELP Please??
    By green_eel in forum C Programming
    Replies: 3
    Last Post: 03-12-2003, 04:36 PM
  5. Replies: 4
    Last Post: 01-29-2002, 02:42 AM