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

Popular posts from this blog

Delphi XE2 Indy10 udp client-server interchange using SendBuffer-ReceiveBuffer -

Qt ActiveX WMI QAxBase::dynamicCallHelper: ItemIndex(int): No such property in -

Enable autocomplete or intellisense in Atom editor for PHP -