| typedef long double float_t; |
| typedef long int32_t; |
| typedef char uint8_t; |
| |
| //float to bits conversion utilities... |
| union clvalue { |
| int32_t i; |
| float f; //must use a float type, else types dont match up |
| }; |
| |
| int32_t floatToIntBits(float_t value) |
| { |
| clvalue u; |
| int32_t e, f; |
| u.f = value; |
| e = u.i & 0x7f800000; |
| f = u.i & 0x007fffff; |
| |
| if (e == 0x7f800000 && f != 0) |
| u.i = 0x7fc00000; |
| |
| return u.i; |
| } |
| float_t intBitsToFloat(int32_t bits) |
| { |
| clvalue u; |
| u.i = bits; |
| return u.f; |
| } |
| |
| float_t byteToFloat(uint8_t b) { |
| if (b == 0) // zero is a special case |
| return 0.0f; |
| int32_t mantissa = b & 7; |
| int32_t exponent = (b >> 3) & 31; |
| int32_t bits = ((exponent+(63-15)) << 24) | (mantissa << 21); |
| return intBitsToFloat(bits); |
| } |
| |
| uint8_t floatToByte(float_t f) { |
| if (f < 0.0f) // round negatives up to zero |
| f = 0.0f; |
| |
| if (f == 0.0f) // zero is a special case |
| return 0; |
| |
| int32_t bits = floatToIntBits(f); // parse float_t into parts |
| int32_t mantissa = (bits & 0xffffff) >> 21; |
| int32_t exponent = (((bits >> 24) & 0x7f) - 63) + 15; |
| |
| if (exponent > 31) { // overflow: use max value |
| exponent = 31; |
| mantissa = 7; |
| } |
| |
| if (exponent < 0) { // underflow: use min value |
| exponent = 0; |
| mantissa = 1; |
| } |
| |
| return (uint8_t)((exponent << 3) | mantissa); // pack into a uint8_t |
| } |
| |
| |
| #ifdef __CLASSIC_C__ |
| int main(){ |
| int ac; |
| char*av[]; |
| #else |
| int main(int ac, char*av[]){ |
| #endif |
| //well known conversion |
| if ( floatToByte(0.5f) != 120 ) |
| return 1; |
| |
| //converting back works? |
| if ( floatToByte(byteToFloat(57)) != 57 ) |
| return 1; |
| |
| return 0; |
| } |