兩個整型 a b,如何不使用比較運算符,將 a 賦值為a 與 b 中的較大值?
GCC專門有一條優化,把各種各樣的奇葩寫法「還原」成(a &< b) ? b : a
。
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/match.pd;h=349eab61d6b3e158c520586f3b35aa1b9157c62d;hb=HEAD#l2844
/* Undo fancy way of writing max/min or other ?: expressions,
like a - ((a - b) -(a &< b)), in this case into (a &< b) ? b : a.
People normally use ?: and that is what we actually try to optimize. */
(for cmp (simple_comparison)
(simplify
(minus @0 (bit_and:c (minus @0 @1)
(convert? (negate@4 (convert? (cmp@5 @2 @3))))))
(if (INTEGRAL_TYPE_P (type)
INTEGRAL_TYPE_P (TREE_TYPE (@4))
TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE
INTEGRAL_TYPE_P (TREE_TYPE (@5))
(TYPE_PRECISION (TREE_TYPE (@4)) &>= TYPE_PRECISION (type)
|| !TYPE_UNSIGNED (TREE_TYPE (@4)))
(GIMPLE || !TREE_SIDE_EFFECTS (@1)))
(cond (cmp @2 @3) @1 @0)))
(simplify
(plus:c @0 (bit_and:c (minus @1 @0)
(convert? (negate@4 (convert? (cmp@5 @2 @3))))))
(if (INTEGRAL_TYPE_P (type)
INTEGRAL_TYPE_P (TREE_TYPE (@4))
TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE
INTEGRAL_TYPE_P (TREE_TYPE (@5))
(TYPE_PRECISION (TREE_TYPE (@4)) &>= TYPE_PRECISION (type)
|| !TYPE_UNSIGNED (TREE_TYPE (@4)))
(GIMPLE || !TREE_SIDE_EFFECTS (@1)))
(cond (cmp @2 @3) @1 @0)))
/* Similarly with ^ instead of - though in that case with :c. */
(simplify
(bit_xor:c @0 (bit_and:c (bit_xor:c @0 @1)
(convert? (negate@4 (convert? (cmp@5 @2 @3))))))
(if (INTEGRAL_TYPE_P (type)
INTEGRAL_TYPE_P (TREE_TYPE (@4))
TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE
INTEGRAL_TYPE_P (TREE_TYPE (@5))
(TYPE_PRECISION (TREE_TYPE (@4)) &>= TYPE_PRECISION (type)
|| !TYPE_UNSIGNED (TREE_TYPE (@4)))
(GIMPLE || !TREE_SIDE_EFFECTS (@1)))
(cond (cmp @2 @3) @1 @0))))
有一說一,確實沒有用比較運算符。
__asm__ volatile("cmpl %2, %1
"
"cmovl %2, %0
"
: "=r"(a)
: "r"(a), "r"(b));
這個問題我和我的同學討論過,但很遺憾我們只得出了a,b為正整數的做法
有趣的問題系列-僅能使用加減乘除,主函數,分別輸出兩個數的最大值和最小值 - 東北小蟹蟹 - 博客園?www.cnblogs.com
原文來自@東北小蟹蟹 ,dbxxx yyds!
用減法獲得大小關係,在最高位上
用間接定址[]替代跳轉
int max[2]={a,b},min[2]={b,a},s=(b-a)&>&>31;
a=max[s];
b=min[s];
性能優化時,為了減少分支命中壓力,這是減少跳轉的標準做法。
a=std::max(a, b);
推薦閱讀: