您的位置:首页 > 其它

用Groovy实现判断两个int数值大小(不用比较运算符,考虑溢出)

2009-05-02 12:24 916 查看
刚读了老紫竹的blog: 不用比较运算符,判断int型的a,b两数的大小,考虑溢出问题.

自己试着实现了一下,用的是个苯法子 -- 把数值部分转换成0或1,再跟sign-bit整合。 谁还有更好的算法? 不妨share一下。

我是用Groovy实现的,基本上调用的都是Java的API,在JVM上同样是BYTECODE,就算是Java的*等价*代码吧。如大家要求的话,我可以把它转成纯Java code。

PS: 我的实现在int compare3(),老紫竹原算法的groovy实现是int compare2(),int compare1()是不考虑溢出的简单实现。

int compare(int a, int b)
{
//return compare1(a, b)  //naive implementation
//return compare2(a, b)  //老紫竹's implementation
return compare3(a, b)  //newmike's implementation
}
int compare1(int a, int b) //naive implementation without overflow concern
{
return (int)(a-b)
}
int compare2(int a, int b) //老紫竹's implementation - with overflow concern but can NOT differentiate '>'(0) from '=='(0)
{
return (int)((a.longValue()-b.longValue())>>>63)
}
int compare3(int a, int b) //newmike's implementation - with overflow concern AND -1 as <; 0 as ==; +1 as >;
{
long diff = a.longValue() - b.longValue()
showLong 'diff', diff
long sign = diff>>>63<<63
showLong 'sign', sign
long val = 0L
long mask = 1L
for(i in 0..<32) //use looping for shorten code, can be replaced by 32 repeated statement groups without implicit compare operators!
{
val |= (diff & mask)
val <<= 1
mask <<= 1
}
showLong 'val[1]', val
val = val << 31 >>> 1
showLong 'val[2]', val
val |= sign
showLong 'val[3]', val
val >>= 62
return (int)val
}
// show debugging info
debugging=false
def showLong(String msg, long l)
{
if(debugging)
println String.format(' --- %-6s : %#-18X', msg, l)
}
// test cases for compare operations
def formatStr = '%1$-5s %2$#-12X  =  %2$+d%n'
printf formatStr, '<0', compare(1, 2)
printf formatStr, '=0', compare(2, 2)
printf formatStr, '>0', compare(2, 1)
println()
printf formatStr, '<0', compare(1, 3)
printf formatStr, '=0', compare(3, 3)
printf formatStr, '>0', compare(3, 1)
println()
printf formatStr, '<0', compare(Integer.MIN_VALUE, Integer.MAX_VALUE)
printf formatStr, '=0', compare(Integer.MIN_VALUE, Integer.MIN_VALUE)
printf formatStr, '=0', compare(Integer.MAX_VALUE, Integer.MAX_VALUE)
printf formatStr, '>0', compare(Integer.MAX_VALUE, Integer.MIN_VALUE)


运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: