Bit shift of signed byte strange behaviour - java

I have written a function to print the bit out in a byte. This happens by setting the most significant bit to 1 comparing it to the inputbyte and if it is also 1 printing "1" else "0". The comparison byte is then shifted right.
How do I achieve starting with 10000000 and shifting to 01000000 then 00100000...
I believe my problem is caused by promotion to int then recasting but I don't see the solution.
package errorreporting;
public class ErrorReporting {
ErrorReporting() {
}
public static void main(String[] args) {
ErrorReporting myError = new ErrorReporting();
byte myByte = 16;
myError.printByteArray(myByte);
}
public void printByteArray(byte inputByte) {
// print out 1 or 0
byte comparison = -128;
for (int x = 0; x < 8; x++) {
if ((inputByte & comparison) != 0) {
System.out.print("1");
} else {
System.out.print("0");
}
// System.out.print(" comparison : " + comparison);
comparison = (byte) (comparison >>> 1);
}
System.out.println(" : " + inputByte);
}
}
This post has some info : Java bitshift strangeness

I believe my problem is caused by promotion to int then recasting
Yes, it is a combination of some implicit and explicit casting and sign extension:
All arguments are first promoted to int before the shift operation takes place, see also https://stackoverflow.com/a/3948303/1611055
Due to 1., your unsigned shift operator >>> does not help - it correctly shifts a 0 into the leftmost position, but since the source argument -128 has been promoted to int before the shift is applied (resulting in 0xffffff80), you end up with 0x7fffffc0 after the first shift.
The simplest solution is to use an int for your mask:
int comparison = 0x80; // -128;
Theoretically, you could also still use a byte for the mask, but then you need to explicitly convert it to an int while discarding the sign bit at the same time, before applying the shift operator, like this:
byte comparison = -128;
...
comparison = (byte)( (((int) comparison) & 0xff) >>> 1);
((int) comparison) & 0xff) assumes that the byte should really be "unsigned" and converts it to the corresponding "unsigned" int value. Then, you can apply the shift operator (>> or >>> does not matter, since we have a positive int value in any case) and cast it back to a byte.

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;
}
}

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).

represent an integer using binary in java language

Here is the problem:
You're given 2 32-bit numbers, N & M, and two bit positions, i & j. write a method to set all bits between i and j in N equal to M (e.g. M becomes a substring of N at locating at i
and starting at j)
For example:
input:
int N = 10000000000, M = 10101, i = 2, j = 6;
output:
int N = 10001010100
My solution:
step 1: compose one mask to clear sets from i to j in N
mask= ( ( ( ((1<<(31-j))-1) << (j-i+1) ) + 1 ) << i ) - 1
for the example, we have
mask= 11...10000011
step 2:
(N & mask) | (M<<i)
Question:
what is the convenient data type to implement the algorithm? for example
we have int n = 0x100000 in C, so that we can apply bitwise operators on n.
in Java, we have BitSet class, it has clear, set method, but doesnt support
left/right shift operator; if we use int, it supports left/right shift, but
doesnt have binary representation (I am not talking about binary string representation)
what is the best way to implement this?
Code in java (after reading all comments):
int x = Integer.parseInt("10000000000",2);
int x = Integer.parseInt("10101",2);
int i = 2, j = 6;
public static int F(int x, int y, int i, int j){
int mask = (-1<<(j+1)) | (-1>>>(32-i));
return (mask & x ) | (y<<i);
}
the bit-wise operators |, &, ^ and ~ and the hex literal (0x1010) are all available in java
32 bit numbers are ints if that constraint remains int will be a valid data type
btw
mask = (-1<<j)|(-1>>>(32-i));
is a slightly clearer construction of the mask
Java's int has all the operations you need. I did not totally understand your question (too tired now), so I'll not give you a complete answer, just some hints. (I'll revise it later, if needed.)
Here are j ones in a row: (1 << j)-1.
Here are j ones in a row, followed by i zeros: ((1 << j) - 1) << i.
Here is a bitmask which masks out j positions in the middle of x: x & ~(((1 << j) - 1) << i).
Try these with Integer.toBinaryString() to see the results. (They might also give strange results for negative or too big values.)
I think you're misunderstanding how Java works. All values are represented as 'a series of bits' under the hood, ints and longs are included in that.
Based on your question, a rough solution is:
public static int applyBits(int N, int M, int i, int j) {
M = M << i; // Will truncate left-most bits if too big
// Assuming j > i
for(int loopVar = i; loopVar < j; loopVar++) {
int bitToApply = 1 << loopVar;
// Set the bit in N to 0
N = N & ~bitToApply;
// Apply the bit if M has it set.
N = (M & bitToApply) | N;
}
return N;
}
My assumptions are:
i is the right-most (least-significant) bit that is being set in N.
M's right-most bit maps to N's ith bit from the right.
That premature optimization is the root of all evil - this is O(j-i). If you used a complicated mask like you did in the question you can do it in O(1), but it won't be as readable, and readable code is 97% of the time more important than efficient code.

best way to reverse bytes in an int in java

What's the best way to reverse the order of the 4 bytes in an int in java??
You can use Integer.reverseBytes:
int numBytesReversed = Integer.reverseBytes(num);
There's also Integer.reverse that reverses every bit of an int
int numBitsReversed = Integer.reverse(num);
java.lang.Integer API links
public static int reverseBytes(int i)
Returns the value obtained by reversing the order of the bytes in the two's complement representation of the specified int value.
public static int reverse(int i)
Returns the value obtained by reversing the order of the bits in the two's complement binary representation of the specified int value.
Solution for other primitive types
There are also some Long, Character, and Short version of the above methods, but some are notably missing, e.g. Byte.reverse. You can still do things like these:
byte bitsRev = (byte) (Integer.reverse(aByte) >>> (Integer.SIZE - Byte.SIZE));
The above reverses the bits of byte aByte by promoting it to an int and reversing that, and then shifting to the right by the appropriate distance, and finally casting it back to byte.
If you want to manipulate the bits of a float or a double, there are Float.floatToIntBits and Double.doubleToLongBits that you can use.
See also
Wikipedia/Bitwise operation
Bit twiddling hacks
I agree that polygenelubricants's answer is the best one. But just before I hit that, I had the following:
int reverse(int a){
int r = 0x0FF & a;
r <<= 8; a >>= 8;
r |= 0x0FF & a;
r <<= 8; a >>= 8;
r |= 0x0FF & a;
r <<= 8; a >>= 8;
r |= 0x0FF & a;
return r;
}
shifting the input right, the output left by 8 bits each time and OR'ing the least significant byte to the result.

Categories