c,宏,必然是位数的单位

时间:2014-02-17 15:56:42

标签: c macros

我有一个宏,它应该返回一定数量的uint。我使用宏,因为这是静态数组的大小。最近,我尝试使用16位系统而失败了:

#define LCD_PIXEL_PER_CHAR    5
#define LCD_CHAR_PER_LINE 16
#define    BITMAP_SIZE        ((LCD_PIXEL_PER_CHAR * LCD_CHAR_PER_LINE)/(sizeof(int)*8)+1)

现在对于32位系统,我的80位适合3个uint和一些余数。 但在16位时,80除以16 = 5 uints,我的宏返回6.显然,+1是错误的,应该重新设计。

有人有一个聪明的解决方案吗?感谢

4 个答案:

答案 0 :(得分:2)

在条件表达式中使用检查确切拟合:

#define BITMAP_SIZE \
  (  (LCD_PIXEL_PER_CHAR * LCD_CHAR_PER_LINE) / (sizeof(int) * 8) \
   + ((LCD_PIXEL_PER_CHAR * LCD_CHAR_PER_LINE) % (sizeof(int) * 8) ? 1 : 0))

答案 1 :(得分:1)

通常,如果在分割前添加n,则会将n - 1四舍五入的结果四舍五入。在你的情况下:

#define INT_BITS (sizeof(int) * 8)
#define BITMAP_SIZE ( (LCD_PIXEL_PER_CHAR * LCD_CHAR_PER_LINE + INT_BITS - 1) / INT_BITS)

答案 2 :(得分:1)

为了速度,您可以测试80位是否可以除以整数的位数:

#define LCD_PIXEL_PER_CHAR 5
#define LCD_CHAR_PER_LINE 16    
#define LINE_BITS (LCD_PIXEL_PER_CHAR*LCD_CHAR_PER_LINE)
#define INT_BITS (sizeof(int)<<3)
#define BITMAP_SIZE (LINE_BITS/INT_BITS+((LINE_BITS&(INT_BITS-1))|(INT_BITS-1)))

答案 3 :(得分:0)

几天后,我在linux内核中找到了一个优雅的解决方案:

/* How many bits in an unsigned int */
#define BitsPerInt (8 * sizeof(unsigned int))

/* howmany(a,b) : how many elements of size y needed to hold all of x */
#define howmany(x, y) (((x)+((y)-1))/(y))

/* How many unsigned int of n bits */
#define IntsPerBits(n) howmany(n, BitsPerInt) 

因此可以很容易地确定数组的大小:

#define     BITMAP_SIZE     IntsPerBits(LCD_PIXEL_PER_CHAR * LCD_CHAR_PER_LINE)