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);
sign 		=0.0f;
exponent	=0;
fraction	=0;


Leave a Reply

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

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

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s