floating point - How to quadruple an unsigned number using bit-wise and logic operator in C -
goal:
4x ( 4.400000095 ) = 17.60000038
- legal ops: integer/unsigned operations incl. ||, &&. if, while
- max ops: 30
- return bit-level equivalent of expression x + x + x + x for
- floating point argument f.
my code:
unsigned 4x(unsigned uf) { unsigned expn = (uf >> 23) & 0xff; unsigned sign = uf & 0x80000000; unsigned frac = uf & 0x007fffff; if (expn == 255 || (expn == 0 && frac == 0)) return uf; if (expn) { expn << 2; } else if (frac == 0x7fffff) { frac >> 2; expn << 2; } else { frac <<= 2; } return (sign) | (expn << 23) | (frac);
}
as can guess, code not work. instead of quadrupling input, input doubled. don't know why since fraction , exponent being right / left shifted 2 instead of 1. im working single precision floating point values in 32 bit machines.
some untested code - leave op. (gtg)
the tricky bit dealing sub-normal numbers when *4 become normal. watch large values overflow infinity. if want ignore sub-normals, expn += 2
, check overflow.
another approach expn += 2
normal numbers. sub-normals, shift frac <<= 2
, handle cases become normal.
code 30 ops.
#include <stdint.h> float x4(float x) { // use union access bits. leap-of-faith here (float 32 bits, endian) union { float f; uint32_t u32; } u; u.f = x; uint32_t expn = (u.u32 >> 23) & 0xff; uint32_t sign = u.u32 & 0x80000000; uint32_t frac = u.u32 & 0x007fffff; // nan inf if (expn == 255) return u.f; if (expn == 0) { expn++; // bring sub-normal normal expo range } else { frac += 0x800000; // restore implied bit } // *4 frac <<= 2; // normalize - iterates twice, less sub-normals while (frac > 0xffffff) { expn++; frac >>= 1; // 1's not shifted out 2 lsb 0 no later rounding } // overflow inf if (expn >= 255) { expn = 255; frac = 0; } else if (frac & 0x800000) { frac ^= 0x800000; // clear implied bit } else { // still sub-normal expn--; // should 0 } u.u32 = sign | (expn << 23) | frac; return u.f; }
Comments
Post a Comment