/* * isTmax - returns 1 if x is the maximum, two's complement number, * and 0 otherwise * Legal ops: ! ~ & ^ | + * Max ops: 10 * Rating: 1 */ intisTmax(int x){ return !(x + 1 + x + 1) & !!(~x); }
我们发现最大值两倍加二为0,但是要排除 -1(补码全为1)后面!!(~x) 就是这个逻辑。
x 01111111 11111111 11111111 11111111 x + 1 10000000 00000000 00000000 00000000 x + 1 + x 11111111 11111111 11111111 11111111 x + 1 + x + 1 00000000 00000000 00000000 00000000
allOddBits
/* * allOddBits - return 1 if all odd-numbered bits in word set to 1 * where bits are numbered from 0 (least significant) to 31 (most significant) * Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 12 * Rating: 2 */ intallOddBits(int x){ int e = 0xAA | (0xAA << 8); e = e | (e << 16); return !((e & x) ^ e); }
// 10101010 10101010 10101010 10101010 int a = 0xAA; // 00000000 00000000 00000000 10101010 int b = 0xAA << 8; // 00000000 00000000 10101010 00000000 int c = a | b; // 00000000 00000000 10101010 10101010 int d = c << 16; // 10101010 10101010 00000000 00000000 int e = c | d; // 10101010 10101010 10101010 10101010
/* * floatScale2 - Return bit-level equivalent of expression 2*f for * floating point argument f. * Both the argument and result are passed as unsigned int's, but * they are to be interpreted as the bit-level representation of * single-precision floating point values. * When argument is NaN, return argument * Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while * Max ops: 30 * Rating: 4 */ unsignedfloatScale2(unsigned uf){ // sign exp frac // 1 8 23 unsigned sign = (uf >> 31) & 0x01; unsignedexp = (uf >> 23) & 0xFF; unsigned frac = uf & 0x7FFFFF; // 特殊 if (exp == 0xFF) { return uf; } // 非规格化 elseif (exp == 0) { frac = frac << 1; return (sign << 31) | (exp << 23) | frac; } // 规格化 else { exp ++; return (sign << 31) | (exp << 23) | frac; } }
先分别求出 sign ,exp 和 frac,如果是特殊值直接返回,在判断是否是规格化,分别处理。
floatFloat2Int
/* * floatFloat2Int - Return bit-level equivalent of expression (int) f * for floating point argument f. * Argument is passed as unsigned int, but * it is to be interpreted as the bit-level representation of a * single-precision floating point value. * Anything out of range (including NaN and infinity) should return * 0x80000000u. * Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while * Max ops: 30 * Rating: 4 */ intfloatFloat2Int(unsigned uf){ // sign exp frac // 1 8 23 unsigned sign = (uf >> 31) & 0x01; unsignedexp = (uf >> 23) & 0xFF; unsigned frac_v = uf & 0x7FFFFF;
// E = exp - Bias = exp - 127 int E = exp - 127; // 超过范围 if (E >= 31) { return0x80000000u; } // 小数 if (E < 0) { return0; }
/* * floatPower2 - Return bit-level equivalent of the expression 2.0^x * (2.0 raised to the power x) for any 32-bit integer x. * * The unsigned value that is returned should have the identical bit * representation as the single-precision floating-point number 2.0^x. * If the result is too small to be represented as a denorm, return * 0. If too large, return +INF. * * Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while * Max ops: 30 * Rating: 4 */ unsignedfloatPower2(int x){ // 非规格化最小值 // 0 00000000 00000000000000000000001 // E = 1 - Bias = 1 - 127 = 126 // frac = 1 * 2^-22 // M = frac // V = 2^E * M = 2^-148 if (x < -148) { return0; }
// 非规格化最大值 // 0 000000 111111111111111111111111 // E = 1 - Bias = 1 - 127 = -126 // frac = 1 (近似,小于) // M = frac // V = 2^E * M = 2^-126 (近似,小于) if (x < -126) { return1 << (x + 148); }
// 规格化最大值 // 0 11111110 11111111111111111111111 // E = exp - Bias = 254 - 127 = 127 // M = 1 + frac = 1.111111111111111111111111 // V = 2^E * M = 2^128 (近似,小于) if (x >= 128) { return0xFF << 23; }
// 规格化最小值 // 0 00000001 00000000000000000000000 // E = exp - Bias = 1 - 127 = -126 // M = 1 + frac = 1 // V = 2^E * M = 2^-126 if (x >= -126) { intexp = x + 127; returnexp << 23; } return0; }