c - 使用宏从一组给定的不同值中查找不等于任何值的值

标签 c math macros c-preprocessor

问题:如何实现一个扩展为整型常量表达式的宏E,使得...

(E != (X) && E != (Y) && E != (Z))

...对于 XYZ 的每个选择作为具有不同的非负值的整数常量表达式的计算结果为 1?

例子:

#define X               13
#define Y               45
#define Z               76
#define E               FUNC(X,Y,Z)
#define FUNC(X,Y,Z)     ??

E /* evaluates to any number distinct from all of 13, 45, and 76 */

使用哪个公式?有什么想法吗?

最佳答案

Given any 3 numbers X, Y and Z, produce an int constant that is different from all 3 values.

显然 0123 必须满足条件。所以这是一个解决方案:

#define FUNC(x,y,z)  (((x) != 0 && (y) != 0 && (z) != 0) ? 0 : \
                      ((x) != 1 && (y) != 1 && (z) != 1) ? 1 : \
                      ((x) != 2 && (y) != 2 && (z) != 2) ? 2 : 3)

这是一个更微妙的解决方案,根据最后一个计算结果为 0123每个参数的 2 位,但只对参数求值一次:

#define FUNC(x,y,z)  ((int)((0x10201030102010 >>           \
                             (4 * ((1 << ((x) & 3)) |      \
                                   (1 << ((y) & 3)) |      \
                                   (1 << ((z) & 3))))) & 3))

解释:

  • 我们组成一个介于 1 和 14 之间的数字,如果其中一个参数的最后 2 位具有此值,则每个位都被设置。
  • 将此值乘以 4,然后将魔数(Magic Number) 0x10201030102010 移动那么多,然后掩码 3,以选择一个不同于所有余数的值。

可读性较差的版本将乘以 2 并移位 0x484C484,仅使用 32 位算法:

#define FUNC(x,y,z)  ((int)((0x484C484 >> ((2 << ((x) & 3)) | \
                                           (2 << ((y) & 3)) | \
                                           (2 << ((z) & 3)))) & 3))

关于c - 使用宏从一组给定的不同值中查找不等于任何值的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71452192/

相关文章:

c++ - 如何在每个新模块中自动注入(inject)辅助类?

macros - 是否可以编写一个计算项目并生成枚举的宏?

java - 同步实际时间(java,c)

c++ - 从整数 vector 生成大小为 k 的下一个组合

java - 如何定义和初始化一个生成 2 到 20(含)随机整数的变量?

algorithm - 生成具有成对不同行和列的随机矩阵

c - 这个 foreach C 宏有多邪恶?

c++ - 为什么许多 VM 看起来具有 C++ 功能却用 C 编写?

c - 通过 Makefile 构建并构建脚本有效,但等效的 Makefile.am 没有。(给出 undefined reference 错误)

c - 套接字编程 - listen() 和 accept() 有什么区别?