0

假设我的 C 代码使用了一个常数RANGEMAX,它是 10 的最大幂int。我可以用以下方式定义它:

#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

在宏预处理阶段是否有更智能的方法来进行如此简单的计算?

由于这些是“简单”的计算,我更喜欢像我这样的普通人通过阅读代码就能理解的解决方案。

4

2 回答 2

3

INT_MAX定义为至少 32767(即 2^15-1)。如int签名所示,实际上您只需要检查 2^15-1、2^31-1 和(理论上)2^63-1。这将减小#if块的大小。

于 2014-12-14T21:13:01.323 回答
1

通过一系列测试确定 的大致范围INT_MAX,可以进行 1、10、100、10000、100000000、10000000000000000 等的乘法运算。

以下应该适用于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_MAXpower(2,15)-1, 或power(2,31)-1power(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
于 2014-12-15T00:33:51.117 回答