使用位运算符比较两个整数
我需要使用Bit运算符比较两个整数。 我遇到了一个问题,我必须比较两个整数而不使用比较运算符。使用位运算符会有所帮助。但是如何?
让我们说a = 4; b = 5;
我们必须表明a不等于b。 但是,我想进一步扩展它,比方说,我们将展示哪个更大。这里b更大..
您至少需要与0进行比较,并且从概念上讲,这是CPU为比较所做的事情。 例如
等于可以建模为^
因为位必须相同才能返回0
(a ^ b) == 0
如果这是C
你可以放弃== 0
因为这可以暗示
!(a ^ b)
但在Java中,如果没有至少一些比较,则无法将int
转换为boolean
。
为了比较,你通常做一个减法,虽然一个处理溢出。
(long) a - b > 0 // same as a > b
减法与添加负数相同,负数与~x + 1相同,所以你可以这样做
(long) a + ~ (long) b + 1 > 0
要删除+1
您可以将其更改为
(long) a + ~ (long) b >= 0 // same as a > b
您可以使用>>
<<
&
|
来实现+
作为一系列逐位操作 和^
但我不会对你造成这种情况。
如果没有Peter提到的比较运算符,则无法将1
或0
转换为bool
。 没有比较运算符,仍然可以获得max
。
我使用bit
(1或0)而不是int
来避免混淆。
bit msb(x): return lsb(x >> 31) bit lsb(x): return x &1 // returns 1 if x < 0, 0 if x >= 0 bit isNegative(x): return msb(x)
有了这些助手isGreater(a, b)
看起来像,
// BUG: bug due to overflow when a is -ve and b is +ve // returns 1 if a > b, 0 if a <= b bit isGreater_BUG(a, b): return isNegative(b - a) // possible overflow
我们需要两个辅助函数来检测相同和不同的符号,
// toggles lsb only bit toggle(x): return lsb(~x) // returns 1 if a, b have same signs (0 is considered +ve). bit isSameSigns(a, b): return toggle(isDiffSigns(a, b)) // returns 1 if a, b have different signs (0 is considered +ve). bit isDiffSigns(a, b): return msb(a ^ b)
所以随着溢出问题的解决,
// returns 1 if a > b, 0 if a <= b bit isGreater(a, b): return (isSameSigns(a, b) & isNegative(b - a)) | (isDiffSigns(a, b) & isNegative(b))
请注意, isGreater
适用于输入isGreater
和0, -5
。
正确实现isPositive(x)
更为棘手 ,因为0
也将被视为正数。 因此,不使用isPositive(a - b)
,而是使用isPositive(a - b)
isNegative(b - a)
作为isNegative(x)
正确地用于0
。
现在max可以实现为,
// BUG: returns 0 when a == b instead of a (or b) // returns a if a > b, b if b > a int max_BUG(a, b): return isGreater(a, b) * a + // returns 0 when a = b isGreater(b, a) * b //
为了修复那个助手是使用了isZero(x)
,
// returns 1 if x is 0, else 0 bit isZero(x): // x | -x will have msb 1 for a non-zero integer // and 0 for 0 return toggle(msb(x | -x))
所以当a = b
时修复,
// returns 1 if a == b else 0 bit isEqual(a, b): return isZero(a - b) // or isZero(a ^ b) int max(a, b): return isGreater(a, b) * a + // a > b, so a isGreater(b, a) * b + // b > a, so b isEqual(a, b) * a // a = b, so a (or b)
也就是说,如果isPositive(0)
返回1,则max(5, 5)
将返回10而不是5.因此正确的isPositive(x)
实现将是,
// returns 1 if x < 0, 0 if x >= 0 bit isPositive(x): return isNotZero(x) & toggle(isNegative(x)) // returns 1 if x != 0, else 0 bit isNotZero(x): return msb(x | -x)
使用二进制二进制补码表示法
int findMax( int x, int y) { int z = x - y; int i = (z >> 31) & 0x1; int max = x - i * z; return max; }
参考: 这里
a ^ b = c // XOR the inputs // If a equals b, c is zero. Else c is some other value c[0] | c[1] ... | c[n] = d // OR the bits // If c equals zero, d equals zero. Else d equals 1
注意: a,b,c
是n位整数, d
是位
java中的解决方案,不使用比较器运算符:
int a = 10; int b = 12; boolean[] bol = new boolean[] {true}; try { boolean c = bol[a ^ b]; System.out.println("The two integers are equal!"); } catch (java.lang.ArrayIndexOutOfBoundsException e) { System.out.println("The two integers are not equal!"); int z = a - b; int i = (z >> 31) & 0x1; System.out.println("The bigger integer is " + (a - i * z)); }
- 对于IOS和Android,Gluon * Mobile * JavaFX公开了哪个Java发行版“级别” – 即Full JavaSE(桌面版)还是Android版?
- 在PLSQL Oracle中抛出特定的错误消息…在hibernate中捕获?
- 如何从ttf文件中获取汉字笔画顺序?
- 有没有一种优雅的方式来应对二十一点的王牌?
- 如何使用Saxon java库命令行工具执行schematronvalidation?
- 为什么Java会自动解码URI编码文件名中的%2F?
- 警告:建议不要在没有服务器身份validation的情况下建立SSL连接
- 使用iText将行添加到PDF表格中
- 如何在Groovy中设置final字段