编译时数字的位位置

时间:2014-02-27 16:53:15

标签: c embedded c-preprocessor compile-time fixed-point

我在使用C的嵌入式系统上实现定点数学。

为了便于阅读,我将分母称为2的幂:

#define Fixed_Point_Base 4096U

然而,当我转换到固定点数学时,我需要移位数量:

#define Fixed_Point_Bit_Position 12U

为了使维护更容易并且代码更健壮,我希望根据Fixed_Point_Base数字获得位置(移位数)#define

#define Fixed_Point_Bit_Position(x) {/*...*/}

我知道的唯一方法涉及对数和除法,我真的不想在嵌入式系统中使用对数或除法:

bit count = ln(4096) / ln(2)

我正在寻找一个预处理器宏或编译时解决方案,它返回2的幂位位置。

我的网络搜索已经在代码中返回了示例,但不是编译时/预处理器解决方案。

仅供参考,我正在使用带有ARM7TDMI处理器的IAR Embedded Workbench 编辑1:我正在使用Parasoft Static Analysis和Coverity Static Analysis工具的MISRA C 2004指南。答案必须通过这些限制。

3 个答案:

答案 0 :(得分:0)

你的问题与我的一个老问题密切相关:

Is there any way to compute the width of an integer type at compile-time?

接受的答案可以解决您的问题:

https://stackoverflow.com/a/4589384/379897

特别是,使用:

#define Fixed_Point_Bit_Position(x) IMAX_BITS((x)-1)

其中IMAX_BITS是该答案中的一个宏。

答案 1 :(得分:0)

您可以通过定义位精度并从那里确定Fixed_Point_Base来反向执行您当前正在执行的操作:

#define PRECISIONS_IN_BITS ( 12 )
#define FIXED_POINT_BASE   ( 1 << PRECISION_IN_BITS )

这样您只能维护一个号码。

答案 2 :(得分:0)

蛮力适用于此!

生成C级常量表达式的简单(好的,“简单”)解决方案(可用于编译时常量,如数组大小):

#define Fixed_Point_Base 4096U

#define FPB_BITSET(X, K) (((Fixed_Point_Base >> (X) & 1) == 1) ? (X) : (K))
#define MAX_FP_BIT_32 FPB_BITSET(31, FPB_BITSET(30, FPB_BITSET(29, FPB_BITSET(28, FPB_BITSET(27, FPB_BITSET(26, FPB_BITSET(25, FPB_BITSET(24, \
                      FPB_BITSET(23, FPB_BITSET(22, FPB_BITSET(21, FPB_BITSET(20, FPB_BITSET(19, FPB_BITSET(18, FPB_BITSET(17, FPB_BITSET(16, \
                      FPB_BITSET(15, FPB_BITSET(14, FPB_BITSET(13, FPB_BITSET(12, FPB_BITSET(11, FPB_BITSET(10, FPB_BITSET(9, FPB_BITSET(8, \
                      FPB_BITSET(7, FPB_BITSET(6, FPB_BITSET(5, FPB_BITSET(4, FPB_BITSET(3, FPB_BITSET(2, FPB_BITSET(1, FPB_BITSET(0, -1 \
                      ))))))))))))))))))))))))))))))))
const unsigned int Fixed_Point_Bit_Position = MAX_FP_BIT_32;

为了我的粘贴手指限制为32位:扩展它是微不足道的。看似鲜为人知的事实是三元运算符是一个常数表达式。

仅预处理程序版本(如果需要标记粘贴结果或其他内容):

#define FPB_BITSET(X) (((Fixed_Point_Base >> (X) & 1) == 1) * (X))

#if FPB_BITSET(31)
#  define Fixed_Point_Bit_Position 31
#elif FPB_BITSET(30)
#  define Fixed_Point_Bit_Position 30
#elif FPB_BITSET(29)
#  define Fixed_Point_Bit_Position 29
#elif //etc...