如何仅使用按位操作返回最多三个无符号整数,例如!,〜,|,&,^,+,>>,<<。我不知道从哪里开始。任何帮助将不胜感激。
编辑:
我只被允许使用给定的合法操作,就是这样。
/** maxOfThree - Returns the maximum of three integers.
* NOTE: x, y, z are all in the range [0, TMax].
* Examples: maxOfThree(1, 2, 3) = 3
* Legal Ops: ! ~ & ^ | + << >>
* Max Ops: 25
int maxOfThree(int x, int y, int z) {
}
答案 0 :(得分:5)
看看&#34; bit-twiddling hacks&#34;页面并研究如何实现最大/最小。
如果你能弄清楚两个数字的最大值是如何工作的,那么你可以概括三个数字的情况。
让我向您解释获得最大值的两位数字:
-(a<b)
可以返回-1或0,然后你可以有11111111 11111111 11111111 11111111
(对于int的两个补码中的-1)或00000000 00000000 00000000 00000000
(-0 =对于int而言= 0。
记住a^b^b = a
和a^b^a = b
(不管订单是什么,这是xor操作),你在第一种情况下就是这样:
a < b
你需要返回b作为结果,那么 a ^ ((a ^ b) & -(a < b))
必须等于a ^ a ^ b
..实际上它是-(a<b)
返回11111111 11111111 11111111 11111111
,并且按位和&amp;在11111111 11111111 11111111 11111111
上操作无符号整数会使数字保持不变...因此a ^ a ^ b = b
。这是最大值。
a > b
则a < b
为假,那么(anything & 00000000 00000000 00000000 00000000)
为0.因此您有a ^ 0
,即a。最大。最后,我们将解决方案推广为三个数字:
#include <stdio.h>
int getMax(unsigned int a, unsigned int b, unsigned int c) {
int temp = a ^ ((a ^ b) & -(a < b)) ;
int r = c ^ ((c ^ temp) & -(c < temp));
return r;
}
int main(void) {
unsigned int a = 3, b = 1, c = 9;
printf("%d", getMax(a,b,c));
return 0;
}
编辑:如果您不允许使用&#34;&lt;&#34;然后使用第二个版本
x - ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1)));
并记住以下摘录
请注意,1989 ANSI C规范没有指定结果 签名右移,所以这些都不便携。如果抛出异常 在溢出时,x和y的值应该是无符号或转换为 没有签名的减法,以避免不必要的投掷 例外,右移需要一个带符号的操作数来产生 所有一位都是负数,所以转为签名
编辑II:这应该适用于您发布的规范:
#include <stdio.h>
int getMax(int x, int y, int z) {
int r = (x + ~((x+~y+1) & ((x+~y+1) >> 31))+1); // if possible use sizeof(int)*sizeof(char)+~0 instead of 31
int r2 = (z + ~((z+~r+1) & ((z+~r+1) >> 31))+1); // if possible use sizeof(int)*sizeof(char)+~0 instead of 31
return r2;
}
int main(void) {
unsigned int a = 5, b = 7, c = 1;
printf("%d", getMax(a,b,c));
return 0;
}
请注意,如果你可以使用sizeof()而不是假设int是4个字节(在所有平台上都不是真的那样)会更好。
答案 1 :(得分:0)
如果你被允许使用-
(你建议+
),我建议以下(未经测试),我觉得比比特翻页更有效,特别是如果第一个最大值为一个宏,我们知道我们正在处理签名的整数。
#define MAX2(a,b) (a-((a-b) >> (sizeof(int) * CHAR_BIT - 1))*(b-a))
int
max3 (int x, int y, int z)
{
return MAX2(MAX2(x, y), z);
}
在大多数平台上, CHAR_BIT
应为#define
'到8。
这也依赖于负数右移的未定义行为。
如果您不允许使用-
,请使用~
并添加1。