假设我的C代码使用的常量RANGEMAX
是int
中拟合的10的最大幂。我可以用:
#include <limits.h>
#if (INT_MAX < 1)
#define RANGEMAX ERROR1
#elif (INT_MAX >= 1) && (INT_MAX < 10)
#define RANGEMAX 1
#elif (INT_MAX >= 10) && (INT_MAX < 100)
#define RANGEMAX 10
#elif (INT_MAX >= 100) && (INT_MAX < 1000)
#define RANGEMAX 100
... /* well, you get the picture */
#elif (INT_MAX >= 10000000000000000)
#define RANGEMAX ERROR2
#endif
在宏预处理阶段是否有更聪明的方法进行这种简单的计算?
因为这些是简单的&#34;计算,我更喜欢只有阅读代码才能让像我这样的普通人理解的解决方案。
答案 0 :(得分:3)
INT_MAX
被定义为至少32767(即2 ^ 15-1)。由于int
已签名,实际上您只需要检查2 ^ 15-1,2 ^ 31-1和(理论上)2 ^ 63-1。这会减少#if
块的大小。
答案 1 :(得分:1)
通过一系列测试确认INT_MAX
的近似范围,可以乘以1,10,100,10000,1000000000000000000000000等。
以下内容适用于10000 <= INT_MAX < power(10,32)
#include <stdio.h>
#include <limits.h>
#define F1(x) (1)
#define F2(x) (((x) >= 10) ? 10 * F1((x)/10): F1(x))
#define F3(x) (((x) >= 100) ? 100 * F2((x)/100): F2(x))
#define F4(x) (((x) >= 10000) ? 10000 * F3((x)/10000): F3(x))
#define F5(x) (((x) >= 100000000) ? 100000000 * F4((x)/100000000): F4(x))
#define ITEST (INT_MAX)
#if ITEST/10000 >= 10000
#if ITEST/100000000 >= 100000000
#define INT10_MAX (10000000000000000 * F6(ITEST/10000000000000000))
#else
#define INT10_MAX (100000000 * F5(ITEST/100000000))
#endif
#else
#define INT10_MAX (10000 * F4(ITEST/10000))
#endif
int main(void) {
printf("%d\n", ITEST);
printf("%d\n", INT10_MAX);
return 0;
}
务实的方法可能假设INT_MAX
为power(2,15)-1
,或power(2,31)-1
,power(2,63)-1
。在使用32位范围之外的值时,宏算术需要注意。
#if INT_MAX/10000 == 3
#define INT10_MAX 10000
#elif INT_MAX/1000000000 == 2
#define INT10_MAX 1000000000
#elif INT_MAX/1000000000/1000000000 == 9
#define INT10_MAX 1000000000000000000
#else
#error Unusual INT_MAX
#endif