問題:如何實作一個E擴展為整數常量運算式的宏,這樣......
(E != (X) && E != (Y) && E != (Z))
... 對于每個選擇 , 和 作為具有不同非負值的整數常量運算式,計算結果X為Y1 Z?
例子:
#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 */
使用哪個公式?有任何想法嗎?
uj5u.com熱心網友回復:
給定任何 3 個數字和
X,產生一個不同于所有 3 個值的常數。YZint
很明顯0,1、2或3必須滿足條件。所以這里有一個解決方案:
#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)
這是一個更微妙的解決方案,評估為、0或取決于每個引數的最后 2 位,但只評估引數一次:123
#define FUNC(x,y,z) ((int)((0x10201030102010 >> \
(4 * ((1 << ((x) & 3)) | \
(1 << ((y) & 3)) | \
(1 << ((z) & 3))))) & 3))
解釋:
- 我們組成一個介于 1 和 14 之間的數字,如果其中一個引數的最后 2 位具有該值,則每個位都被設定。
- 將此值乘以
4并將幻數移動0x10201030102010那么多,然后將掩碼乘以 3 以選擇與所有余數不同的值。
可讀性較差的版本將僅使用 32 位算術乘以2和 shift :0x484C484
#define FUNC(x,y,z) ((int)((0x484C484 >> ((2 << ((x) & 3)) | \
(2 << ((y) & 3)) | \
(2 << ((z) & 3)))) & 3))
uj5u.com熱心網友回復:
雖然不如@chqrlie第一個答案那么直接,但我想添加以下發現:
只需要 2 位
x, y, z即可生成獨特的值。
如果所有 3 個中的最低有效位x,y,z相同,則回傳x^1。
否則^ 2跟不同x,y,z。
#define FUNC2BITS(x,y,z) ( \
(((x)&1 == (y)&1) && ((y)&1 == (z)&1)) ? (x)^1 : \
(((x)&1 == (y)&1) ) ? (z)^2 : \
(((x)&1 == (z)&1) ) ? (y)^2 : (x)^2)
#define FUNC(x,y,z) FUNC2BITS((x)&3, (y)&3, (z)&3)
以上不依賴于x,y,z不同,也不將它們限制為非負數。由于 OP 具??有“具有不同的非負值”,因此可以簡化為
#define FUNC2BITS(x,y,z) ( \
(((x)&1 == (y)&1) ) ? (z)^2 : \
(((x)&1 == (z)&1) ) ? (y)^2 : (x)^2)
uj5u.com熱心網友回復:
想法:找到當前的最大值/最小值和(如果可以的話)加/減1:
#include <limits.h>
#define FUNC(X,Y,Z) \
MAX(X,MAX(Y,Z)) < INT_MAX ? MAX(X,MAX(Y,Z)) 1 : \
MIN(X,MIN(Y,Z)) > 0 ? MIN(X,MAX(Y,Z))-1 : \
-1 /* hard case: don't know yet how to implment */
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
int x1 = FUNC(23,45,78); // 79
int x2 = FUNC(0,45,78); // 79
int x3 = FUNC(23,INT_MAX,78); // 22
int x4 = FUNC(0,1,2); // 3
int x5 = FUNC(INT_MAX,34,0); // -1 (hard case)
如果不能加/減1(例如0, 45, INT_MAX),那么“還不知道”。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/442978.html
下一篇:如何檢查組中是否存在欄位?
