该方法接收一个n位2的补码数,我们试图找到它的绝对值,以及该数字的位数。以下是一些例子:
abs(0x00001234,16); // => 0x00001234
abs(0x00001234,13); // => 0x00000DCC
所以你可以看到,在第一个例子中,0x00001234只是自我产生,因为16位有足够的前导零才能成为它自己。
但是,对于第二个示例,使用13位使0x00001234在符号位中有1,因此当您将此13位数转换为正数时,它会产生0x00000DCC。
我觉得我到目前为止应该工作,但在某些情况下它不起作用:/ 知道什么是错的或我应该走哪条路?
编辑:也忘了提及,我们不能使用>>>,或+, - ,*,/除非我们只是递增1。
public static int abs(int num, int n)
{
boolean set = ((1 << n-1) & num) == (1 << n-1);
if (!set) {
return num;
} else {
int bitmask = (0x7FFFFFFF >> (32-n)) | (1 << n-1);
return (num ^ bitmask) + 1;
}
}
答案 0 :(得分:2)
哇,在这里,你会选择以后来的人:
public static int abs(int num, int n)
{
int topbit = 1<<(n-1);
int ones = (topbit<<1)-1;
num &= ones; // sanity check
if (0==(topbit&num)) {
return num;
} else {
return (num ^ ones) + 1;
}
}
所以问题是,是否可以从此处删除操作以使此功能更快?
答案 1 :(得分:0)
这是错误的
int bitmask = 0xFFFFFFFF >> (32 - n);
它将始终为0xFFFFFFFF,使用
int bitmask = 0xFFFFFFFF >>> (32 - n);
请参阅http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19
更新我从您的评论中了解到,您不能使用无符号班次。在这种情况下,请尝试
int bitmask = (int) (0xFFFFFFFFL >> (32 - n));
完整代码
public static int abs(int num, int n) {
int bitmask = (int) (0xFFFFFFFFL >> (32 - n));
boolean set = ((1 << n - 1) & num) != 0;
if (!set) {
return num & bitmask;
} else {
return -(num | ~bitmask);
}
}