Cod*_*rSS 3 c floating-point bit-manipulation
我发现自己需要计算16位无符号整数除以2的幂,这将导致32位浮点数(标准IEEE格式).这是在嵌入式系统上,并且例程被重复使用,所以我正在寻找更好的东西(float)x/(float)(1<<n)
.另外,C编译器非常有限(没有数学库,位字段,reinterpret_cast等).
如果你不介意一点点,那么显而易见的方法是将整数转换为float,然后从指数位中减去n以实现除以2 ^ n:
y = (float)x; // convert to float
uint32_t yi = *(uint32_t *)&y); // get float value as bits
uint32_t exponent = yi & 0x7f800000; // extract exponent bits 30..23
exponent -= (n << 23); // subtract n from exponent
yi = yi & ~0x7f800000 | exponent; // insert modified exponent back into bits 30..23
y = *(float *)&yi; // copy bits back to float
Run Code Online (Sandbox Code Playgroud)
请注意,对于x = 0,这会失败,因此您应该在转换前检查x> 0.
总成本是一个int-float转换加上一些整数按位/算术运算.如果使用union,则可以避免使用单独的int/float表示,只需直接在float上工作即可.
使用ldexpf(x, -n)
。这个函数是由 C 标准定义的,它可以完全满足您的要求,返回x \xe2\x80\xa22 -n,因此任何像样的编译器都会为此提供良好的代码。(这需要数学库的一部分或编译器将其优化为内联代码。)
如果n
在编译时已知,您也可以考虑x * (1.f/(1<<n))
. 一个好的编译器会(1.f/(1<<n))
在编译时进行计算,因此可执行代码将是两个操作:转换x
为float
常量并乘以常量。ldexpf(x, -n)
如果编译器没有优化的话,这可能比生成的代码更快ldexpf(x, -n)
。
归档时间: |
|
查看次数: |
1118 次 |
最近记录: |