Reputation: 387
Working on a method that would take in an integer (num) and an integer (n) that would take the absolute value of an n-bit number. I believe my logic is correct, have done it on paper and it worked out but the code seems like it is off. All help is greatly appreciated!
/**
* Take the absolute value of an n-bit number.
*
* Examples:
* abs(0x00001234, 16); // => 0x00001234
* abs(0x00001234, 13); // => 0x00000DCC
*
* Note: values passed in will only range from 1 to 31 for n.
*
* @param num An n-bit 2's complement number.
* @param n The bit length of the number.
* @return The n-bit absolute value of num.
*/
public static int abs(int num, int n)
{
int shifter = num << (n+1);
int newInt = num & ~shifter;
return newInt;
}
Upvotes: 2
Views: 408
Reputation: 18780
I don't think there's a single bitmask that will work for both positive and negative cases.
First test if the number is negative by checking that the nth bit is 1; if not, return the original, else return the two's complement.
Something like this looks like it works:
public static int abs(int num, int n)
{
int shifter = -1 << (n - 1);
if ((num & shifter) == 0)
return num;
shifter = shifter << 1;
return (~num + 1) & ~shifter;
}
For example, suppose you pass in 0x1FFF as a 16 bit number, so it's positive.
-1 << 15
would be 0xFFFF8000 (0's for the lowest 15 bits, 1's for the rest), 0xFFFF8000 & 0x00001FFF is 0, and your return the original.
If on the other hand 0x1FFF is treated as only 13 bits, then it's negative. num & shifter
will be 1 because both have the 13th bit set. Now do the two's complement by flipping bits and adding ones. Because you'll be flipping all 32 bits, you need to use a bitmask to zero out all the remaining ones. The original shifter
works if you push it one more bit to the left and invert it.
Upvotes: 1
Reputation: 63708
Use -1
(all 1 bits) for shifter.
int shifter = -1 << n;
Upvotes: 1