我在使用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指南。答案必须通过这些限制。
答案 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...