howManyBits
/* howManyBits - 返回用二进制补码表示x所需的最小位数
* 示例: howManyBits(12) = 5
* howManyBits(298) = 10
* howManyBits(-5) = 4
* howManyBits(0) = 1
* howManyBits(-1) = 1
* howManyBits(0x80000000) = 32
* 合法操作: ! ~ & ^ | + << >>
* 最大操作数: 90
* 难度: 4
*/
逻辑:利用二分法,逼近最高位1对应的位数
(1)将负数转换为其按位取反值
(2)检查前16位,若存在1,则至少需要16位,x>>16,否则x>>0
(3)
IEEE 754 单精度浮点数表示法
单精度浮点数的表示方式如下:
- 符号位(S):第 31 位 表示数值的正负。
- 阶码(E):第 30 到第 23 位 表示数值的指数。
- 尾数(M):第 22 到第 0 位 表示数值的有效数字。
非规格数:
- 符号位(s):1位。
- 阶码部分(E):8位,全为0。
- 尾数部分(f):23位,直接用于表示数值,不包含隐含的1。
floatScale2 :
2*f的位级等效形式
/*
* floatScale2 - 返回表达式2*f的位级等效形式
* 浮点参数f。
* 参数和结果都作为无符号整数传递,但
* 它们要被解释为单精度浮点值的位级表示。
* 当参数是NaN时,返回参数
* 合法操作: 任何整数/无符号操作包括||, &&。也包括if, while
* 最大操作数: 30
* 难度: 4
*/
注意:
阶码:
(1)阶码达到255(即0x7F800000),则表示结果为无穷大
(2)阶码部分全为 0(非规格化数或0),需要转为规格数
尾数:
(1)规格化数变为无穷大,尾数为0
(2)零和非规格化数,左移尾数一位相当于将数值乘以2。
(3)若左移尾数,可能到24位(esp不为0),成为规格化数
(4)frac <<= 1;左移后赋值,frac << 1左移得到新值但原值未改变
floatFloat2Int:
一个32位的单精度浮点数表示转换为一个32位的整数表示
/*
* floatFloat2Int - 返回表达式(int) f的位级等效形式
* 浮点参数f。
* 参数作为无符号整数传递,但
* 它要被解释为单精度浮点值的位级表示。
* 任何超出范围的值(包括NaN和无穷大)应返回
* 0x80000000u。
* 合法操作: 任何整数/无符号操作包括||, &&。也包括if, while
* 最大操作数: 30
* 难度: 4
*/
注意:
二进制:
(1)0x80000000u
为无符号整数
阶码 真实指数(阶码值 - 127偏移量):
(1)小于1(exp <= 0),返回0
(2)超出int 32位整数范围(exp大于31),返回无穷大
尾数:
(1)通过 frac |= 0x00800000
,我们在尾数中强制设置第24位为1,将其转换为 1.M
的形式
(2)尾数frac(1.M , 23位二进制数M),通过esp位数左移右移得到结果作为result
floatPower2
返回表达式2.0^x的位级等效形式
/*
* floatPower2 - 返回表达式2.0^x的位级等效形式
* (2.0的x次方)对于任何32位整数x。
*
* 返回的无符号值应该具有与单精度浮点数2.0^x相同的位级表示。
* 如果结果太小,无法表示为非正规数,则返回0。如果太大,返回+INF。
*
* 合法操作: 任何整数/无符号操作包括||, &&。也包括if, while
* 最大操作数: 30
* 难度: 4
*/
注意:
(1)+INF(正无穷大).0x7F800000
- 符号位 S = 0(正数)
- 阶码 E = 255(全为1,二进制
11111111
) - 尾数 M = 0
(2)x(真实指数) (-126 ~ -149)(非规范化浮点数)不超出尾数范围,返回尾数
测试结果:
Points Rating Errors Points Ops Puzzle
1 1 0 2 7 bitXor
1 1 0 2 1 tmin
1 1 0 2 8 isTmax
2 2 0 2 7 allOddBits
2 2 0 2 2 negate
3 3 0 2 11 isAsciiDigit
3 3 0 2 8 conditional
3 3 0 2 5 isLessOrEqual
4 4 0 2 6 logicalNeg
4 4 0 2 36 howManyBits
4 4 0 2 12 floatScale2
4 4 0 2 17 floatFloat2Int
4 4 0 2 9 floatPower2
Score = 62/62 [36/36 Corr + 26/26 Perf] (129 total operators)