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..."
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.