Get length of bits used in int - java

If you have the binary number 10110 how can I get it to return 11111? e.g a new binary number that sets all bits to 1 after the first 1, there are some likewise examples listed below:
101 should return 111 (3 bit length)
011 should return 11 (2 bit length)
11100 should be return 11111 (5 bit length)
101010101 should return 111111111 (9 bit length)
How can this be obtained the easiest way in Java? I could come up with some methods but they are not very "pretty".

My try: Integer.highestOneBit(b) * 2 - 1

You could use this code:
int setBits (int value)
{
value |= (value >> 1);
value |= (value >> 2);
value |= (value >> 4);
value |= (value >> 8);
value |= (value >> 16);
return value;
}
The idea is that leftmost 1 will get copied to all positions on the right.
EDIT: Also works fine with a negative value. If you replace int with long, add one extra |= statement: value |= (value >> 32). In general, last shift must be a power of 2 that is at least half of value size in bits.

Haven't tested, but something like this should be okay:
long setBits(long number) {
long n = 1;
while (n <= number) n <<= 1;
return n - 1;
}

Not most efficient, but simplest,
int i = (1 << (int)(Math.log(n)/Math.log(2)+1)) - 1;
It will work for first 31 bit of int and first 63 bit for long.

Related

How to fill high-end bits in a Java byte with '1' without knowing the last 1 in advance? (FAST FIX Negative Integer decoder)

I am writing a FIX/FAST decoder for negative numbers as described below:
My question is:
How to fill the high-end bits of a Java byte with 1s as it is described above? I am probably unaware of some bit manipulation magic I need to in this conversion.
So I need to go from 01000110 00111010 01011101 to 11110001 10011101 01011101.
I know how to shift by 7 to drop the 8th bit. What I don't know is how to fill the high-end bits with 1s.
It seems like the question you're asking doesn't really match up with the problem you're trying to solve. You're not trying to fill in the high bits with 1; you're trying to decode a stop-bit-encoded integer from a buffer, which involves discarding the sign bits while combining the payload bits. And, of course, you want to stop after you find a byte with a 1 in the stop bit position. The method below should decode the value correctly:
private static final byte SIGN_BIT = (byte)0x40;
private static final byte STOP_BIT = (byte)0x80;
private static final byte PAYLOAD_MASK = 0x7F;
public static int decodeInt(final ByteBuffer buffer) {
int value = 0;
int currentByte = buffer.get();
if ((currentByte & SIGN_BIT) > 0)
value = -1;
value = (value << 7) | (currentByte & PAYLOAD_MASK);
if ((currentByte & STOP_BIT) != 0)
return value;
currentByte = buffer.get();
value = (value << 7) | (currentByte & PAYLOAD_MASK);
if ((currentByte & STOP_BIT) != 0)
return value;
currentByte = buffer.get();
value = (value << 7) | (currentByte & PAYLOAD_MASK);
if ((currentByte & STOP_BIT) != 0)
return value;
currentByte = buffer.get();
value = (value << 7) | (currentByte & PAYLOAD_MASK);
if ((currentByte & STOP_BIT) != 0)
return value;
currentByte = buffer.get();
value = (value << 7) | (currentByte & PAYLOAD_MASK);
return value;
}
A loop would be cleaner, but I unrolled it manually since messaging protocols tend to be hot code paths, and there's a fixed maximum byte length (5 bytes). For simplicity's sake, I read the bytes from a ByteBuffer, so you may need to adjust the logic based on how you're reading the encoded data.
Fillig the high bits might go as:
int fillHighBits(int b) { // 0001abcd
int n = Integer.highestOneBit(b); // 00010000
n = ~n; // 11101111
++n; // 11110000
return (n | b) 0xFF; // 1111abcd
}
As expression
(~Integer.highestOneBit(b) + 1) | b
Though the examples you gave lets me doubt this is what you want.
This can be done very simply using a simple accumulator where you shift in 7 bits at a time. You need to keep track of how many bits you have in the accumulator.
Sign extension can be performed by simple logical shift left follwed by arithmetic shift right (by the same distance) to copy the topmost bit to all unused positions.
byte[] input = new byte[] { 0x46, 0x3A, (byte) 0xDD };
int accumulator = 0;
int bitCount = 0;
for (byte b : input) {
accumulator = (accumulator << 7) | (b & 0x7F);
bitCount += 7;
}
// now sign extend the bits in accumulator
accumulator <<= (32 - bitCount);
accumulator >>= (32 - bitCount);
System.out.println(Integer.toHexString(accumulator));
The whole trick is that >>N operator replicates the top bit N times.
do logical OR (|) with a number which has highend bits set to 1 and rest are 0
for example:
1010101010101010
OR 1111111100000000
--------------------
11111111101010101
something like this:
int x = ...;
x = x | 0xF000;

how to get absolute value of a number in java using bit manipulation

I want to implement a function to get the absolute value of a number in java: do nothing if it is positive, if it is negative, convert to positive.
I want to do this only using bit manipulations and no number comparators.
Please help
Well a negation:
-n
Is the same as the two's complement:
~n + 1
The problem is here you only want to negate if the value is < 0. You can find that out by using a logical shift to see if the MSB is set:
n >>> 31
A complement would be the same as an XOR with all 1's, something like (for a 4-bit integer):
~1010 == 1010 ^ 1111
And we can get a mask with the arithmetic right shift:
n >> 31
Absolute value says:
if n is < 0, negate it (take the complement and add 1 to it)
else, do nothing to it
So putting it together we can do the following:
static int abs(int n) {
return (n ^ (n >> 31)) + (n >>> 31);
}
Which computes:
if n is < 0, XOR it with all 1's and add 1 to it
else, XOR it with all 0's and add 0 to it
I'm not sure there's an easy way to do it without the addition. Addition involves any number of carries, even for a simple increment.
For example 2 + 1 has no carry:
10 + 1 == 11
But 47 + 1 has 4 carries:
101111 + 1 == 110000
Doing the add and carry with bitwise/bit shifts would basically just be a loop unroll and pointless.
(Edit!)
Just to be silly, here is an increment and carry:
static int abs(int n) {
int s = n >>> 31;
n ^= n >> 31;
int c;
do {
c = (n & s) << 1;
n ^= s;
} while((s = c) != 0);
return n;
}
The way it works is it flips the first bit, then keeps flipping until it finds a 0. So then the job is just to unroll the loop. The loop body can be represented by a somewhat ridiculous compound one-liner.
static int abs(int n) {
int s = n >>> 31;
n ^= n >> 31;
int c = (n & s) << 1;
c = ((n ^= s) & (s = c)) << 1; // repeat this line 30 more times
n ^= s;
return n;
}
So there's an abs using only bitwise and bit shifts.
These aren't faster than Math.abs. Math.abs just returns n < 0 ? -n : n which is trivial. And actually the loop unroll totally sucks in comparison. Just a curiosity I guess. Here's my benchmark:
Math.abs: 4.627323150634766ns
shift/xor/add abs: 6.729459762573242ns
loop abs: 12.028789520263672ns
unrolled abs: 32.47122764587402ns
bit hacks abs: 6.380939483642578ns
(The bit hacks abs is the non-patented one shown here which is basically the same idea as mine except a little harder to understand.)
you can turn a two's-compliment number positive or negative by taking it's logical negation
i = ~i; // i equals not i
You can use the Math.max() function to always get the positive
public static int abs(int i) {
return Math.max(i,~i);
}
This depends on what type of number you are using. For an int, use
int sign = i >> 31;
This gets the sign bit, which is 0 for positive numbers, and 1 for negative numbers. For other primitive types, replace 31 with the number of bits used for the primitive minus 1.
You can then use that sign in your if statement.
if (sign == 1)
i = ~i + 1;
I think you'll find that this little ditty is what you're looking for:
int abs(int v) {
int mask = v >> Integer.SIZE - 1;
return v + mask ^ mask;
}
It's based on Bit Twiddling Hacks absolute value equation and uses no comparison operations. If you aren't allowed to use addition, then (v ^ mask) - mask is an alternative. The value of this function is fairly questionable; since it's nearly as clear as the implementation of Math.abs and it's only marginally faster (at least on a i7):
v + mask ^ mask: 2.0844380704220384 abs/ns
(v ^ mask) - mask: 2.0819764093030244 abs/ns
Math.abs: 2.2636355843860656 abs/ns
Here's a test that proves that it works over the entire range of integers (the test runs in less than 2 minutes on an i7 processor under Java 7 update 51):
package test;
import org.hamcrest.core.Is;
import org.junit.Assert;
import org.junit.Test;
public class AbsTest {
#Test
public void test() {
long processedCount = 0L;
long numberOfIntegers = 1L << Integer.SIZE; //4294967296L
int value;
for (value = Integer.MIN_VALUE; processedCount < numberOfIntegers; value++) {
Assert.assertEquals((long) abs(value), (long) StrictMath.abs(value));
if (processedCount % 1_000_000L == 0L) {
System.out.print(".");
}
processedCount++;
}
System.out.println();
Assert.assertThat(processedCount, Is.is(numberOfIntegers));
Assert.assertThat(value - 1, Is.is(Integer.MAX_VALUE));
}
private static int abs(int v) {
int mask = v >> Integer.SIZE - 1;
return v + mask ^ mask;
}
}
This problem can be broken down into 2 simple steps:
1.
If >= 0 then just return the number.
2.
If smaller than 0 (ie. negative), then flip the first bit that indicates that the number is negative. This can easily be done with an XOR operation with -1 and the number; Then simply add +1 to deal with the offset (signed integers start at -1 not 0).
public static int absolute(int a) {
if (a >= 0) {
return a;
} else {
return (a ^ -1) + 1;
}
}

Getting/Setting a bit value from image

Question is based on this site.
Could someone explain the meaning of these lines:
private int getBitValue(int n, int location) {
int v = n & (int) Math.round(Math.pow(2, location));
return v==0?0:1;
}
and
private int setBitValue(int n, int location, int bit) {
int toggle = (int) Math.pow(2, location), bv = getBitValue(n, location);
if(bv == bit)
return n;
if(bv == 0 && bit == 1)
n |= toggle;
else if(bv == 1 && bit == 0)
n ^= toggle;
return n;
}
int v = n & (int) Math.round(Math.pow(2, location));
Math.pow(2, location) raises 2 to the given power. This is rounded and converted to an integer. In binary, this will be 00000001 if location==0, 00000010 if location==1, 00000100 if location==2, etc. (Much better would be 1 << location which shifts a "1" by a certain number of bits, filling in 0 bits at the right. Using Math.pow will probably try to compute the logarithm of 2 every time it's called.)
n & ... is a bitwise AND. Since the item on the right has just one bit set, the effect is to zero out every bit in n except for that one bit, and put the result in v. This means that v will be 0 if that one bit is 0 in n, and something other than 0 if that bit is `, which means
return v==0?0:1;
returns 0 if the bit is clear and 1 if it's set.
int toggle = (int) Math.pow(2, location), bv = getBitValue(n, location);
toggle is set to that Math.pow thing I already described. bv is set to the bit that's already in n, which is 0 or 1. If this equals the thing you're setting it to, then we don't need to do anything to n:
if(bv == bit)
return n;
Otherwise, either we need to set it to 1 (remember that toggle will have just one bit set). n |= toggle is the same as n = n | toggle. | is a bit-wise OR, so that one bit will be set in n and all other bits in n will remain the same"
if(bv == 0 && bit == 1)
n |= toggle;
Or we need to set the bit to 0. n ^= toggle is the same as n = n ^ toggle. n is an exclusive OR. If we get here, then the bit in n is 1, and the bit in toggle is 1, and we want to set the bit in n to 0, so exclusive OR will change that bit to 0 while leaving every other bit the same:
else if(bv == 1 && bit == 0)
n ^= toggle;
The getBitValue just gets the value of a specified bit (on a certain location)
The setBitValue sets the value of a bit on the matched specific location.
These getter/setter methods are usually used for image processing, i.e. if you have a musk and you want to change a specific bit value.
Nothing more or less.

Computing the absolute value of an n-bit 2's complement number

The method takes in an n-bit 2's complement number whose absolute value we're trying to find, and the number of bits that the number will be. Here are some examples:
abs(0x00001234, 16); // => 0x00001234
abs(0x00001234, 13); // => 0x00000DCC
So you can see that in the first example that 0x00001234 just yields itself because with 16 bits it has enough leading zeroes to just be itself.
However, for the second example, using 13 bits makes 0x00001234 have a 1 in the sign bit, so when you convert this 13-bit number to a positive number, it yields 0x00000DCC.
I feel like what I have so far should work, but it isn't working for some cases :/
Any idea what's wrong or what direction I should be going in?
EDIT: Also forgot to mention, we can't use >>>, or +,-,*,/ unless we're just incrementing by 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;
}
}
wha, here you go for people who come by later:
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;
}
}
so the question is, can operations be removed from here to make this function faster?
this is wrong
int bitmask = 0xFFFFFFFF >> (32 - n);
it will always be 0xFFFFFFFF, use
int bitmask = 0xFFFFFFFF >>> (32 - n);
see http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19
UPDATE as I understood from your comment you are not allowed to use unsigned shift. In this case try
int bitmask = (int) (0xFFFFFFFFL >> (32 - n));
full code
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);
}
}

Java - Bit Insertion

I have a long number like:
long l = Long.parseLong("10*000001111110" , 2) ;
Now, I want to add two bits in one position (say 2nd position, marked as *) into the long number.
Like,
long l = Long.parseLong("10*11*000001111110" , 2) ; (given between *)
Can anybody help me how to do that ? Note that I give an example to illustrate what I want. In real, I have only long land I have to work on it.
Edit:
1) position is not constant may be 0, 1 , 2 .. whatever.
2) and msb's can be 0. Means,
long l = Long.parseLong("00000010*000001111110" , 2) ;
long l = Long.parseLong("00000010*11*000001111110" , 2) ;
It sounds like you want something like bitStuffing where masking (&, ~, ^, and |) and shifting (>> and <<) are your instruments of choice.
long insertBit(long p_orignal, long p_new_bits, int p_starting_position_from_right, int p_ending_position_from_right)
{
long returnValue = p_original;
long onlyNewBits = 0;
// Set the bit to zero
long mask = (0xFFFFFFFFFFFFFFFFl);
for (int i=p_starting_position_from_right; i<=p_ending_position_from_right; i++)
{
mask ^ (1l << i);
}
returnValue = returnValue & mask;
mask = ~mask;
onlyNewBits = ~(p_new_bits & mask);
returnValue |= onlyNewBits;
return returnValue;
}
Disclaimer: I don't have a Java compiler available to compile this, but it should be something like this.
The first idea I had is the following:
Extract the first x bits that needs to stay on the position they are (in your example: 10) -> you could do this by running through a loop which creates the appropriate bitmask:
long bitmask = 1;
for(long bit = 1; bit < index; bit++) {
bitmask = (bitmask << 1) | 1;
}
Now you can create the long number that gets inserted -> just shift that number index positions to the left.
After that, you can easily build the new number:
long number = (((oldNumber >> index) << index) << insertionLength) | (insertion << index) | (oldNumber && bitmask);
Note: ((oldNumber >> index) << index) clears out the right part of the number (this part gets appended at the end using the bistmask). then you just need to shift this result by the length of the insertion (make space for it) and or it with the insertion (this needs to get shifted to the left by the index where to insert: (insertion << index). Finally, or the last part of the number (extracted via the bitmask: oldNumber && bitmask) to this result and you are done.
Note: I haven't tested this code. However, generally it should work but you may need to check my shifts (either it is index or index - 1 or so)!
If you only have the Long value say 123 you need to first convert this to a binary string. Like so:
String binaryValue = Long.toBinaryString("123L");
Then we take the string representation and perform a manipulation a specific character like so:
char[] characters = binaryValue.toCharArray();
char desiredCharacter = characters[index];
if(desiredCharacter == '1')
{
if(newValue == '1')
{
desiredCharacter = '0';
}
}else{
if(newValue == '1')
{
desiredCharacter ='1';
}
}
finally we convert the modified characters back into a string like so:
String rebuiltString = new String(characters);
I am sure there are more efficient ways to do this.
Well, if you want to set a specific bit in a number:
To turn it on:
number |= (1 << pos)
if pos = 4: (1<<pos) = 00000000 00000000 00000000 00010000
To turn it off:
number &= ~(1 << pos)
if pos = 4: ~(1<<pos) = 11111111 11111111 11111111 11101111
where pos is the position of the bit (with 0 being the low order bit, and 64 being the high order bit).

Categories