/* *| Name: *| GouldToNative - converts Gould format floating point to native format. *| *| Interface: *| double *| GouldToNative(unsigned char *inVal) *| *| Input: *| inVal - input value, pointer to 4 byte Gould format floating point *| *| Input and Output: *| none *| *| Output: *| none *| *| Return values: *| input value converted to native floating point format *| *| Remarks: *| Gould format description can be found in the NOAA Gvar Transmission *| Format document, section 3.5.4. *| *| Categories: *| converter */ #include <stdio.h> #include <string.h> #include <math.h> double GouldToNative ( unsigned char *inVal ) { double nativeVal; double temp; double dblMant; int compVal; int sign; int exponent; float mant; unsigned char tmpVal[4]; union u_tag{ unsigned char uchar[4]; long l; } u; /* * an example conversion: * * input value (hex): BD DA 4D 07 * a) convert to binary: * 1011 1110 1101 1010 0100 1101 0000 0111 * b) sign bit is set, so take twos complement: * 0100 0001 0010 0101 1011 0010 1111 1001 * c) convert this back to hex: 41 25 B2 F9 * d) mantissa = 2470649 * e) exponent = 65 * f) tempVal = mantissa / 16 exp (70 - 65) * g) outputVal = tempVal * sign = -2.3561944 * */ /* load input into a temporary buffer for munging */ memcpy(tmpVal, inVal, 4); /* determine sign of number; if negative, take 2's complement */ sign = 1; if (tmpVal[0] & 0x80) { sign = -1; /* compVal = TwosComp(* ((int *) inVal)); */ memcpy(u.uchar, inVal, 4); /* printf(" long: %X\n",u.l); */ compVal = ((unsigned long)u.l ^ (unsigned long)0xffffffff) +1; /* printf(" compVal: %X\n",compVal); */ memcpy(tmpVal, &compVal, 4); } /* determine the exponent, biased at 64 */ exponent = (tmpVal[0] & 0x7f); if (exponent == 0) exponent = 64; /* determine the value of the mantissa, load into a double */ mant = (float) (tmpVal[3] + (tmpVal[2] * 256) + (tmpVal[1] * 65536)); dblMant = mant; /* now adjust the mantissa according to the exponent */ temp = pow((double) 16, (double) (70 - exponent)); nativeVal = dblMant / temp; nativeVal = nativeVal * sign; /*printf(" sign:%d output:%lf\n",sign,nativeVal);*/ /* return value as a double, caller can cast if needed */ return nativeVal; }