#include #include #include #include "sics.h" /* * conversions: * hex2float * float2hex * * Markus Zolliker Aug 2010 */ /*-------------------------------------------------------------------------*/ void double2ieee(double input, char ieee[4]) { /* convert double to IEEE 32 bit floating number (denormalized numbers are considered as zero) */ long mantissa; int exponent; if (input == 0) { ieee[0] = 0; ieee[1] = 0; ieee[2] = 0; ieee[3] = 0; } else { mantissa = 0x1000000 * (frexp(fabs(input), &exponent)); exponent = exponent - 1 + 127; if (exponent < 0) { exponent = 0; } else if (exponent > 0xFE) { exponent = 0xFE; } if (input < 0) { ieee[0] = 0x80 | (exponent >> 1); } else { ieee[0] = exponent >> 1; } ieee[1] = (exponent & 1) << 7 | ((mantissa & 0x7F0000) >> 16); ieee[2] = (mantissa & 0xFF00) >> 8; ieee[3] = mantissa & 0xFF; } return; } /*-------------------------------------------------------------------------*/ double ieee2double(char ieee[4]) { /* IEEE 32 bit floating number to double (denormalized numbers are considered as zero) */ long mantissa; double output; int exponent; mantissa = ((ieee[1] << 16) & 0x7FFFFF) | ((ieee[2] << 8) & 0xFF00) | ((ieee[3]) & 0xFF); exponent = (ieee[0] & 0x7F) * 2 + ((ieee[1] >> 7) & 1); /* raw exponent */ if (exponent == 0 && mantissa == 0) { return 0.0; } output = ldexp(mantissa, -23) + 1.0; if (ieee[0] & 0x80) { output = -output; } return output * ldexp(1, exponent - 127); } /*-------------------------------------------------------------------------*/ int CnvrtAction(SConnection *con, SicsInterp *sics, void *data, int argc, char *argv[]) { double f; char ieee[4]; char result[32]; if (argc != 3) goto Usage; if (strcasecmp(argv[1], "float2xieee") == 0) { double2ieee(atof(argv[2]), ieee); SCPrintf(con, eValue, "%2.2x%2.2x%2.2x%2.2x", ieee[0] & 0xFF, ieee[1] & 0xFF, ieee[2] & 0xFF, ieee[3] & 0xFF); return 1; } else if (strcasecmp(argv[1], "xieee2float") == 0) { ieee[0]=0; ieee[1]=0; ieee[2]=0; ieee[3]=0; sscanf(argv[2], "%2hhx%2hhx%2hhx%2hhx", ieee, ieee+1, ieee+2, ieee+3); snprintf(result, sizeof result, "%.7g", ieee2double(ieee)); if (strchr(result, '.') == NULL && strchr(result, 'e') == NULL) { SCPrintf(con, eValue, "%s.", result); } else { SCWrite(con, result, eValue); } return 1; } Usage: SCPrintf(con, eError, "ERROR: Usage: cnvrt float2xieee "); SCPrintf(con, eError, " cnvrt xieee2float "); return 0; }