If I have a binary notation such as "1000010" which equals 66 and I want to increment it by one to "1000011" which equals 67. How is that done correctly in my array? Currently it's printing out "0100010" which is 34, but no where near the correct answer. I don't think my array is shifting correctly, nor will it increase size as the numbers get larger. Although, I can't make any assumptions about how big the array can be other than what's explicitly stated.
public class math {
//=================================================================
// increment(A) returns an array of bits representing A+1.
//=================================================================
public static byte[] increment(byte[] A)
{
byte carry= 1;
for(int i = 0; i<A.length; i++){
byte b = A[i];
A [i] ^= carry;
carry &= b;
}
return A;
}
private static String toBinString (byte [] a)
{
String res = "";
for (int i = 0; i <a. length; i++)
{
res = (a [i] == 0 ? "0": "1") + res;
}
return res;
}
/**
* #param args
*/
public static void main(String[] args) {
byte [] A ={1,0,0,0,0,1,0};
increment(A);
System.out.println (toBinString (A));
}
}
The lazy (and secure) way for increment by one :
String s = "1000010";
for (int i = 0; i < 5; i++) {
System.out.print(s);
System.out.println("\t" + Integer.valueOf(s, 2));
s = Integer.toBinaryString(Integer.valueOf(s, 2) + 1);
}
Output :
1000010 66
1000011 67
1000100 68
1000101 69
1000110 70
(Edited for presentation)
This worked for me:
public static void main(String[] args) {
byte [] A ={1,0,0,0,0,1,0};
increment(A);
System.out.println (toBinString (A));
}
public static byte[] increment(byte[] A) {
boolean carry = true;
for (int i = (A.length - 1); i >= 0; i--) {
if (carry) {
if (A[i] == 0) {
A[i] = 1;
carry = false;
}
else {
A[i] = 0;
carry = true;
}
}
}
return A;
}
private static String toBinString (byte [] a) {
String res = "";
for (int i = 0; i < a. length; i++) {
res += (a [i] == 0 ? "0": "1") ;
}
return res;
}
//Function call
incrementCtr(ctr, ctr.length - 1);
//Increments the last byte of the array
private static void incrementCtr(byte[] ctr, int index) {
ctr[index]++;
//If byte = 0, it means I have a carry so I'll call
//function again with previous index
if(ctr[index] == 0) {
if(index != 0)
incrementCtr(ctr, index - 1);
else
return;
}
}
Late but concise:
public static void increment(byte[] a) {
for (int i = a.length - 1; i >= 0; --i) {
if (++a[i] != 0) {
return a;
}
}
throw new IllegalStateException("Counter overflow");
}
public static byte[] increment(byte[] array) {
byte[] r = array.clone();
for ( int i = array.length - 1; i >= 0; i-- ) {
byte x = array[ i ];
if ( x == -1 )
continue;
r[ i ] = (byte) (x + 1);
Arrays.fill( r, i + 1, array.length, (byte) 0 );
return r;
}
throw new IllegalArgumentException( Arrays.toString( array ) );
}
exception if overflow
In this case you can iterate on all values.
public boolean increment() {
int i = this.byteArray.length;
while (i-->0 && ++this.byteArray[i]==0);
return i != -1;
}
At the end you can increase the array's size.
There are many solutions on this page that represent a native Java byte as a full array of numeric one and zero values. In other words, a single single byte (with 8 bits) is represented as an entire array of 8 individual numeric values (where each index in the array is a byte itself that represents the 1 or 0 value of each bit position).
That means for a given input byte (8 bits), an 8 byte array (64 bits) is used to represent ones and zeros. Consequently, an input byte array of length 4 (e.g. representing an int or unsigned int), would require 32 bytes (256 bits), and an input byte array of length 8 (e.g. for a long) would require 64 bytes (512 bits), and so on.
Thats exponential (O(nc)) complexity - a relatively massive memory/performance expense to do something that the language already supports natively and efficiently. And if there are more than one of these byte array values to work with, that compounds the performance hit further.
The following is a correct (and working) solution if you have a standard byte array representing a single contiguous big-endian bit string and you want to increment it by one bit. It is nearly identical to Cristof R's solution, except that particular solution does not compile.
The following solution is most efficient if you don't need to create a copy of the input byte array, and is useful as an equivalent for iterator incrementation, e.g. i = i + 1 scenarios:
/**
* Treats the specified byte array as a single contiguous big-endian
* bit string, and increments it by a single bit. Does not throw an
* exception on overflow and instead 'rolls' over to zero.
*/
public static void increment(byte[] a) {
for (int i = a.length - 1; i >= 0; --i) {
if (++a[i] != 0) {
break;
}
}
}
If you don't want to modify the source bit string, you can just clone it before incrementing:
byte[] original = new byte[]{0, 0, 0, 0}; //integer value 0
byte[] copy = original.clone();
increment(copy);
Here's a little test program demonstrating:
public class IncrementBitExample {
/**
* Treats the specified byte array as a single contiguous big-endian
* bit string, and increments it by a single bit. Does not throw an
* exception on overflow and instead 'rolls' over to zero.
*/
public static void increment(byte[] a) {
for (int i = a.length - 1; i >= 0; --i) {
if (++a[i] != 0) {
break;
}
}
}
public static String toBinary(byte b) {
String bString = Integer.toBinaryString(b & 0xFF);
return String.format("%8s", bString).replace(' ', '0');
}
public static String toBinary(byte[] bytes) {
StringBuilder sb = new StringBuilder(16);
for(byte b : bytes) {
if (sb.length() > 0) {
sb.append(' '); //separate byte segments for readability
}
String val = toBinary(b);
sb.append(val);
}
return sb.toString();
}
public static void main(String[] args) {
byte[] b = new byte[]{0, 0, 0, 0}; // integer 0
for(int i = 0; i <= 256; i++) {
System.out.println("b: " + toBinary(b));
increment(b); // effectively b = b + 1;
}
}
}
Running main shows the following output (snipped for brevity):
b: 00000000 00000000 00000000 00000000
b: 00000000 00000000 00000000 00000001
b: 00000000 00000000 00000000 00000010
b: 00000000 00000000 00000000 00000011
b: 00000000 00000000 00000000 00000100
b: 00000000 00000000 00000000 00000101
b: 00000000 00000000 00000000 00000110
b: 00000000 00000000 00000000 00000111
b: 00000000 00000000 00000000 00001000
b: 00000000 00000000 00000000 00001001
b: 00000000 00000000 00000000 00001010
b: 00000000 00000000 00000000 00001011
b: 00000000 00000000 00000000 00001100
b: 00000000 00000000 00000000 00001101
b: 00000000 00000000 00000000 00001110
b: 00000000 00000000 00000000 00001111
b: 00000000 00000000 00000000 00010000
... continued ...
b: 00000000 00000000 00000000 11111110
b: 00000000 00000000 00000000 11111111
b: 00000000 00000000 00000001 00000000
Notice the very last printed bit string. The loop iterator max value is 256 and that number cannot be represented as a single unsigned byte - it requires at least two bytes to represent. As a result, the incrementing of the 2nd-to-last bit string value of:
00000000 00000000 00000000 11111111 (integer value 255)
has to 'overflow' to the next byte to the left (big-endian), and produces the final value:
00000000 00000000 00000001 00000000 (integer value 256)
Related
I have a byte array from which I need to read specific bits and convert to int (see the byte array structure below). Even though the bits information I want to read is in 3 bytes, I tried reading 4 bytes (6-9) as integer and then read the bits from that integer value with bits or bitsValue method but somehow I am not able to see the right values from the bit manipulation. And with my expertise in bits I am pretty sure I am doing something wrong.
Can someone please suggest I am doing it correctly and why its not working. Thanks in Advance!!
Byte array is in Little Endian format.
0th byte - Some Value
1st Byte - Some Value
2nd - 5th Byte - Some Value
6th - 9th Byte - first 18 bits represent some value
- Next 5 bits represent some value
- Next 1 bit represent some value
- Last 8 bits represent some value
public class Test {
public static void main(String... dataProvider) {
String s = "46 00 ef 30 e9 08 cc a5 03 43";
byte[] bytes = new byte[s.length()];
bytes = hexStringToByteArray(s);
int bytePointer = 0;
int msgType = getIntFromSingleByte(bytes[bytePointer]); // 0th byte
int version = getIntFromSingleByte(bytes[++bytePointer]); // 1st byte
int tickInMS = getIntValue(bytes, ++bytePointer); // 2nd-5th bytes
bytePointer = bytePointer + 4;
int headr = getIntValue(bytes, bytePointer); // 6th-9th bytes
int utcTime = bits(headr, 0, 18); // 6th-9th bytes - 18 bits
int reserved = bits(headr, 18, 5); // 6th-9th bytes- 5 bits
int reportOrEvent = bits(headr, 23, 1); // 6th-9th bytes - 1 bits
int reportId = bitsValue(headr, 24, 32); // 6th-9th- 8 bits
}
public static int getIntFromSingleByte(byte data) {
return (data & 0xFF);
}
public static int getIntValue(byte[] bytes, int startPosition) {
byte[] dest = new byte[4];
System.arraycopy(bytes, startPosition, dest, 0, dest.length);
return toInt(dest);
}
// took from Stack overflow
static int bits(int n, int offset, int length) {
// shift the bits rightward, so that the desired chunk is at the right end
n = n >> (31 - offset - length);
// prepare a mask where only the rightmost `length` bits are 1's
int mask = ~(-1 << length);
// zero out all bits but the right chunk
return n & mask;
}
public static int bitsValue(int intNum, int startBitPos, int endBitPos) {
// parameters checking ignored for now
int tempValue = intNum << endBitPos;
return tempValue >> (startBitPos + endBitPos);
}
public static byte[] hexStringToByteArray(final String s) {
String[] splits = s.split(" ");
final byte[] data = new byte[splits.length];
for (int i = 0; i < splits.length; i++) {
char first = splits[i].length() < 2 ? '0' : splits[i].charAt(0);
char second = splits[i].length() < 2 ? splits[i].charAt(0) : splits[i].charAt(1);
data[i] = (byte) ((Character.digit(first, 16) << 4) + Character.digit(second, 16));
}
return data;
}
public static int toInt(byte[] data) {
if (data == null || data.length != 4)
return 0x0;
return (int) ((0xff & data[0]) << 24 | (0xff & data[1]) << 16 | (0xff & data[2]) << 8
| (0xff & data[3]) << 0);
}
}
Wrapping your input data in a ByteBuffer will simplify parsing and allow you to adjust endianness as necessary.
Your bits method is wrong. The constant 31 should be 32. Also, the method uses MSB 0 bit numbering, which is odd for little-endian data. You should confirm that your input is documented as using this bit numbering scheme.
Your bitsValue method is wrong too. May as well just use bits after fixing it.
This code is simpler and extracts the bit fields correctly:
public static void main(String... args) {
String s = "46 0 79 37 a8 3 9f 37 1 43 eb 7a f 3 3 fe c4 1 c5 4 c5 5e";
byte[] input = hexStringToByteArray(s);
// Wrap the input in a ByteBuffer for parsing. Adjust endianness if necessary.
ByteBuffer buffer = ByteBuffer.wrap(input).order(ByteOrder.BIG_ENDIAN);
int msgType = buffer.get() & 0xff;
int version = buffer.get() & 0xff;
int tickInMS = buffer.getInt();
int header = buffer.getInt();
int utcTime = bits(header, 0, 18); // 6th-9th bytes - 18 bits
int reserved = bits(header, 18, 5); // 6th-9th bytes - 5 bits
int reportOrEvent = bits(header, 23, 1); // 6th-9th bytes - 1 bit
int reportId = bits(header, 24, 8); // 6th-9th bytes - 8 bits
System.out.printf("utc: %d, report? %d, id: %d\n", utcTime, reportOrEvent, reportId);
}
/**
* Extract a bit field from an int. Bit numbering is MSB 0.
*/
public static int bits(int n, int offset, int length) {
return n >> (32 - offset - length) & ~(-1 << length);
}
Instead of error prone bit mangeling you should rather use the binary string representation of the numbers and do your "bit picking" as string operations:
String s = "46 00 ef 30 e9 08 cc a5 03 43";
String[] hexNumbers = s.split(" ");
for(String hexNumber : hexNumbers) {
String binaryNumber = String.format("%8s", new BigInteger(hexNumber,16).toString(2)).replace(' ','0');
System.out.print(String.format("value in hex : %s, value in binary: %s", hexNumber,binaryNumber));
}
This question already has answers here:
Difference between >>> and >>
(9 answers)
Closed 5 years ago.
int z = -1; int m = z>>1; System.out.println("the values is " +m);
Output is
the values is -1
but my doubt is how it happening internally, Can any explain? Step by step procedure.
int z = 2; int m = z>>1;
the z value in binary
00000000 00000000 00000000 00000010 ,
After the value is shifted then the m value in binary will be as
00000000 00000000 00000000 00000001 , when I print m value it will be as 1, but my question is, what is happening if I use negative value for z variable and when I assign z value with -1 why output variable has -1 itself? ( Two complement will happen are not?)
As described in JLS Sec 15.19:
The value of n >> s is n right-shifted s bit positions with sign-extension. The resulting value is floor(n / 2^s).
So, you are calculating -1 >> 1 == floor(-1 / 2) == floor(-0.5) = -1.
Tried to retrieve some bits of a number, e.g. the marked bits 00001011 of the byte 11 below,
(byte) 11 >> 1 << 6 >> 5
but why is the result 10 instead of 2 ?
#EDIT
To make a method below, the solution from #Yassin Hajaj seems more feasible.
public byte getBits(byte b, int from, int to) { // from & to inclusive
return (byte) (b >> from << (8 - (to - from + 1))) >> (8 - to - 1);
}
getBits((byte) 11, 1, 2); // => 2
Or more universal with the hints from #Andreas,
public <T extends Number> long getBits(T n, int from, int to) {
return n.longValue() >>> from << (64 - (to - from + 1)) >>> (64 - to - 1);
}
getBits((byte) 11, 1, 2); // => 2
You did not specify your initial number to be of the binary system. Taking advantage of binary literals, you could fix this by prefixing the number with 0b. The code then outputs the desired 2
byte b = (byte) 0b11 >> 1 << 6 >> 5;
System.out.println(b); // 2
Another way of getting 2 is to force the cast to byte after having reached << 6 to keep only the last eight bits of the number.
public static void main(String[] args) {
byte b;
b = (byte) (11 >> 1 << 6) >> 5;
System.out.println(b); // 2
}
TL;DR Use b & 6, e.g. (byte)(11 & 6). See working getBits() implementation(s) at the end.
First of all, casting 11 to a byte is rather meaningless, because the >> operator will coerce it right back to an int value.
To show you why your code doesn't work, here is a program that displays all the intermediate steps:
public static void main(String[] args) {
for (byte i = 0; i <= 16; i++) {
int i1 = i >> 1;
int i2 = i1 << 6;
int i3 = i2 >> 5;
System.out.printf("%3d %s -> %3d %s -> %3d %10s -> %3d %s%n", i, bin(i), i1, bin(i1), i2, bin(i2), i3, bin(i3));
}
}
private static String bin(int value) {
String s = Integer.toBinaryString(value);
return "0000000".substring(Math.min(7, s.length() - 1)) + s;
}
Output:
0 00000000 -> 0 00000000 -> 0 00000000 -> 0 00000000
1 00000001 -> 0 00000000 -> 0 00000000 -> 0 00000000
2 00000010 -> 1 00000001 -> 64 01000000 -> 2 00000010
3 00000011 -> 1 00000001 -> 64 01000000 -> 2 00000010
4 00000100 -> 2 00000010 -> 128 10000000 -> 4 00000100
5 00000101 -> 2 00000010 -> 128 10000000 -> 4 00000100
6 00000110 -> 3 00000011 -> 192 11000000 -> 6 00000110
7 00000111 -> 3 00000011 -> 192 11000000 -> 6 00000110
8 00001000 -> 4 00000100 -> 256 100000000 -> 8 00001000
9 00001001 -> 4 00000100 -> 256 100000000 -> 8 00001000
10 00001010 -> 5 00000101 -> 320 101000000 -> 10 00001010
11 00001011 -> 5 00000101 -> 320 101000000 -> 10 00001010
12 00001100 -> 6 00000110 -> 384 110000000 -> 12 00001100
13 00001101 -> 6 00000110 -> 384 110000000 -> 12 00001100
14 00001110 -> 7 00000111 -> 448 111000000 -> 14 00001110
15 00001111 -> 7 00000111 -> 448 111000000 -> 14 00001110
16 00010000 -> 8 00001000 -> 512 1000000000 -> 16 00010000
Your upper bits are not getting cleared, because it's operating on int values. If you change everything to byte, you get:
public static void main(String[] args) {
for (byte i = 0; i <= 16; i++) {
byte i1 = (byte)(i >> 1);
byte i2 = (byte)(i1 << 6);
byte i3 = (byte)(i2 >> 5);
System.out.printf("%3d %s -> %3d %s -> %4d %s -> %3d %s%n", i, bin(i), i1, bin(i1), i2, bin(i2), i3, bin(i3));
}
}
private static String bin(byte value) {
String s = Integer.toBinaryString(value & 0xFF);
return "0000000".substring(s.length() - 1) + s;
}
0 00000000 -> 0 00000000 -> 0 00000000 -> 0 00000000
1 00000001 -> 0 00000000 -> 0 00000000 -> 0 00000000
2 00000010 -> 1 00000001 -> 64 01000000 -> 2 00000010
3 00000011 -> 1 00000001 -> 64 01000000 -> 2 00000010
4 00000100 -> 2 00000010 -> -128 10000000 -> -4 11111100
5 00000101 -> 2 00000010 -> -128 10000000 -> -4 11111100
6 00000110 -> 3 00000011 -> -64 11000000 -> -2 11111110
7 00000111 -> 3 00000011 -> -64 11000000 -> -2 11111110
8 00001000 -> 4 00000100 -> 0 00000000 -> 0 00000000
9 00001001 -> 4 00000100 -> 0 00000000 -> 0 00000000
10 00001010 -> 5 00000101 -> 64 01000000 -> 2 00000010
11 00001011 -> 5 00000101 -> 64 01000000 -> 2 00000010
12 00001100 -> 6 00000110 -> -128 10000000 -> -4 11111100
13 00001101 -> 6 00000110 -> -128 10000000 -> -4 11111100
14 00001110 -> 7 00000111 -> -64 11000000 -> -2 11111110
15 00001111 -> 7 00000111 -> -64 11000000 -> -2 11111110
16 00010000 -> 8 00001000 -> 0 00000000 -> 0 00000000
Here, the problem is the sign-extension you get from >>. Even switching to >>> won't work, because the >>> still coerces to int with sign-extension before the shift happens.
To get rid of sign-extension, you have to convert byte to int using b & 0xFF, because the & will coerce b to an int with sign-extension, then the bitwise AND operator will remove all those bits.
Of course, if you're going to use bitwise AND anyway, just use it to get the desired result, i.e. b & 0b00000110 (or b & 6).
For the same reason as described above, the getBits() method doesn't work.
Solution is to still use a bitwise AND operator, but construct the bit-mask from the supplied from and to values.
The trick here is the use (1 << x) - 1 to create a mask of x bits, e.g. 5 -> 0b00011111. So if you want from 2 to 4 inclusive, build 0x00011111 (5! bits) and 0x00000011 (2 bits), then XOR them to get 0x00011100.
public static byte getBits(byte b, int from, int to) {
if (from < 0 || from > to || to > 7)
throw new IllegalArgumentException();
int mask = ((1 << (to + 1)) - 1) ^ ((1 << from) - 1);
return (byte)(b & mask);
}
0 00000000 -> 0 00000000
1 00000001 -> 0 00000000
2 00000010 -> 2 00000010
3 00000011 -> 2 00000010
4 00000100 -> 4 00000100
5 00000101 -> 4 00000100
6 00000110 -> 6 00000110
7 00000111 -> 6 00000110
8 00001000 -> 0 00000000
9 00001001 -> 0 00000000
10 00001010 -> 2 00000010
11 00001011 -> 2 00000010
12 00001100 -> 4 00000100
13 00001101 -> 4 00000100
14 00001110 -> 6 00000110
15 00001111 -> 6 00000110
16 00010000 -> 0 00000000
For other primitive types, overload the method:
public static byte getBits(byte value, int from, int to) {
if (from < 0 || from > to || to > 7)
throw new IllegalArgumentException();
int mask = ((1 << (to + 1)) - 1) ^ ((1 << from) - 1);
return (byte)(value & mask);
}
public static short getBits(short value, int from, int to) {
if (from < 0 || from > to || to > 15)
throw new IllegalArgumentException();
int mask = ((1 << (to + 1)) - 1) ^ ((1 << from) - 1);
return (short)(value & mask);
}
public static int getBits(int value, int from, int to) {
if (from < 0 || from > to || to > 31)
throw new IllegalArgumentException();
int mask = ((1 << (to + 1)) - 1) ^ ((1 << from) - 1);
return value & mask;
}
public static long getBits(long value, int from, int to) {
if (from < 0 || from > to || to > 63)
throw new IllegalArgumentException();
long mask = ((1L << (to + 1)) - 1) ^ ((1L << from) - 1); // <-- notice the change to long and 1L
return value & mask;
}
So you have 11 base 10 ( 0b1011 aka 0x0B ) and you want the 2's bit and the 4's bit?
Just do a bitwise AND with those two bits ( 0x04 + 0x02 = 0x06 )
x = 11 & 0x06;
Shifting not required
public class UpCase {
public static void main(String[] args) {
int t;
byte val;
val = 123;
for (t = 128; t > 0; t = t / 2) {
System.out.println(t);
if ((val & t) != 0) System.out.println(" 1");
else System.out.println(" 0");
}
}
}
In particular, I am not sure why we are using val=123? I understand that this program will print out 123 in binary but why is that the case? How does this work? I do understand however, the principles of the & operator and how you can turn on and off bits but I am not sure how it works in this particular example?
This program will print out the binary digits of the number in val from MSB to LSB by comparing it to each power of 2:
123 : 01111011 &
128 : 10000000 =
00000000
00000000 != 0 => false, print 0
123 : 01111011 &
64 : 01000000 =
01000000
01000000 != 0 => true, print 1
123 : 01111011 &
32 : 00100000 =
00100000
00100000 != 0 => true, print 1
// repeat for 2^4-2^1...
123 : 01111011 &
1 : 00000001 =
00000001
00000001 != 0 => true, print 1
Very simple:
It just checks if the value (123 in this case) using the bitwise operator &. The result of that is 1 or 0, this process is repeated for the following value 0.5t etc until t=0, resulting in the binary string for this value 123.
I've seen in a few places the following code recommended to add to numbers and divide by 2, particularly in the context of finding a middle index in an array to be quicksorted.
int middle = ( low + high ) >>> 1;
opposed to
int middle = ( low + high ) / 2;
Correct me if I'm wrong on the basics. Right shifting bits 1 position (>> 1) has the effect of dividing by 2. Since in java int is signed we don't want to change the first bit, so we use the unsigned shift operator >>>. I've heard the claim this prevents integer overflow but I don't see how. According to the docs arithmetic operators have presidence over shifts. Which is a moot point since brackets are being used anyways. If whatever's in the the ( ) overflows why would something outside matter?
When you add two ints, the number may overflow into a negative number, but the bits are still there, and no information is lost; it could be interpreted as an unsigned int, if Java had such a type. Let's try to average 2^30 and 2^30 + 2 with this method.
01000000 00000000 00000000 00000000
+ 01000000 00000000 00000000 00000010
-----------------------------------
10000000 00000000 00000000 00000010 // overflow
In Java, this would be interpreted as -2^30 + 2, but if it were unsigned, then it would be interpreted as 2^31 + 2.
Java's unsigned bit-shift-right operator, >>>, shifts in a zero instead of sign-extending.
10000000 00000000 00000000 00000010 >>> 2 yields
01000000 00000000 00000000 00000001
And that's the correct answer, 2^30 + 1.
That is contrast to the signed bit shift operator, >>, which sign-extends:
10000000 00000000 00000000 00000010 >> 2 yields
11000000 00000000 00000000 00000001
That's incorrect, -2^30 + 1.
This will work for averaging two positive int values. But because the result will always be non-negative, this won't work if the correct average value is negative.
Real example:
int low = 0x40000000;
int high = 0x40000002;
int unsigned = (low + high) >>> 1;
int signed = (low + high) >> 1;
System.out.println("low =" + low);
System.out.println("high =" + high);
System.out.println("unsigned=" + unsigned);
System.out.println("signed =" + signed);
The output:
low =1073741824
high =1073741826
unsigned=1073741825
signed =-1073741823
I noticed that there is a typo:
>> 2
should be:
>> 1
and
>>> 2
should be
>>> 1
for the shift operator examples...