IBM32 to IEEE

Processing some seismic data from the classic salt set revealed what appeared to be order of magnitude errors in the trace data. On closer examination of the SEG-y format, turns out the binary data was IBM32 not IEEE, which amounts to different proportions of bits in fraction/exponent. Here’s a little C code to convert IBM32 floats.



//maybe put these guys in *h

#define SIGN_MASK 	2147483648u	//bit 31 	== 1
#define EXPONENT_MASK	2130706432u	//bits 24:30 	== 1
#define FRACTION_MASK	16777215u   	//bits 0:23 	== 1
#define FRACTION_DEN	16777216u   	//bit 24 	== 1

// to convert IBM floats to IEEE

void ktmIBM32toIEEE(unsigned int* input, float* output, int n){
 
 
 
int i;
int j;
//ibm32 format; 31bit = sign, 30:24bits = exponent, 23:0bits = fraction
//exponent is base 16, bias 64
//bit31 is leftmost
 
 
 
//temp vars
float sign	=0.0f;
unsigned int fraction 	=0;
unsigned int exponent 	=0;
 
 
 
for (i=0; i<n; i++){
 
 
 
//4 byte; sign and exponent
 
 
 
sign = (-2.0f * (float) ((input[i] & SIGN_MASK) > 0)) + 1.0f;
exponent = (input[i] & EXPONENT_MASK);
//printf("%u %u\n",input[i],exponent);
 
 //3,2,1 byte; fraction
 
      
 
        fraction = (input[i] & FRACTION_MASK);
 
        //printf("%u %u\n",input[i],fraction);
 

 
 
 
 
 
// bit shift 24 places & remove bias in exp
 
float exp  = (float) ((exponent >> 24) & 127u) - 64.0f;
output[i]=sign * ((float) fraction / (float) FRACTION_DEN) * powf(16.0f,exp);
//printf("%f\n",output[i]);
 
sign 		=0.0f;
exponent	=0;
fraction	=0;
 
 
 
 
 
 
 
}
return;
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s