Meaning of << and |= in Java - java

There is a question of implementing a code in Java where I have to find if the string has unique characters or not without having to create a new data structure.
The Java implementation was as follows:
public static boolean isUniqueChars(String str) {
int checker = 0;
for (int i = 0; i < str.length(); ++i) {
int val = str.charAt(i) - 'a';
if ((checker & (1 << val)) > 0) return false;
checker |= (1 << val);
}
return true;
}
In line 5-6, there's the << that I don't really get.
And in line 6, I don't get what the '|' symbol does.
Could someone give a brief explanation of how this code works?
Thanks.

1. For this symbol : <<
In your code : 1 << val means (int)Math.pow(2,val) = 2 ^ val
2. For this symbol : >>
>> is bit-shift operator
x >> N means (if you view it as a string of binary digits):
The rightmost N bits are discarded
The leftmost bit is replicated as many times as necessary to pad the result to the original size (32 or 64 bits),
e.g.
00000000000000000000000000101011 >> 2 -> 00000000000000000000000000001010
11111111111111111111111111010100 >> 2 -> 11111111111111111111111111110101
3. For this symbol : |=
it means bitwise inclusive OR and assignment operator
E.g:
checker |= (1<<val)
is same as checker |= (2^val)
is same as checker = checker | (2^val) (*)
then : A | B ( | means Binary OR Operator copies a bit if it exists in either operand)
Example
A = 00101010
B = 01101000
A | B = 01101010
with
0 OR 0 = 0 , 1 OR 0 = 1
1 OR 1 = 1 , 0 OR 1 = 1

Using Ziprox's helpful hint that (1 << val) is equivalent to 2^val or Math.pow(2,val). It becomes much easier to decipher what is happening.
I believe 'int' is 4 bytes long which is 32 bits. This method is converting each letter in the alphabet (undercase) to number 2 ^ val. Basically, each letter is represented by a unique bit of the variable checker. 26 letters, 32 bits gives you 6 extra bits that do nothing.
checker & (1<<val)
will only be true of it has seen the number previously.
checker |= (1<<val)
is equivalent to
checker = (checker | (1<<val))
which simply flips that letter's bit from 0 to 1 to indicate that it has been seen.

Related

Reverse bits of a unsigned integer

The below two code is the method can invert the bits of an unsigned 32 bits integer. But What's the difference of the two code below?
Why the first code is wrong and the second code is correct.
I can't see the difference of these two.
public int reverseBits(int n) {
int result = 0;
for (int i = 0; i < 32; i++) {
result = result << 1 | (n & (1 << i));
}
return result;
}
public int reverseBits(int n) {
int result = 0;
for (int i = 0; i < 32; i++) {
result = result << 1 | ((n >> i) & 1);
}
return result;
}
Appreciate any help.
The first code is wrong, because it extracts given bit and puts it in the same position of the resulting number. Suppose you are on iteration i = 5. Then n & (1 << 5) = n & 32 which is either 0 or 0b100000. The intention is to put the one-bit to the lowest position, but when performing | operation it actually puts it to the same position #5. On the consequent iterations you move this bit even higher, so you practically have all the bits or'ed at the highest bit position.
Please note that there are more effective algorithms to reverse bits like one implemented in standard JDK Integer.reverse method:
public static int reverse(int i) {
// HD, Figure 7-1
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i << 24) | ((i & 0xff00) << 8) |
((i >>> 8) & 0xff00) | (i >>> 24);
return i;
}
It has to do with whether the bit being grabbed from n is being stored in the rightmost bit of the result or being stored back into the same position.
Suppose n is 4 (for example).
Then when i is 2, the expression (n & (1 << i))
becomes (4 & (1 << 2)), which should equal 4 & 4, so it evaluates to 4.
But the expression ((n >> i) & 1)
becomes ((4 >> 2) & 1), which should equal 1 & 1, so it evaluates to 1.
The two expressions do not have the same result.
But both versions of the function try to use those results in the exact same way, so the two versions of the function do not have the same result.

Only 7 bits for Java char?

I'm trying to make a UUencode algorithm and part of my code contains this:
for(int x = 0; x < my_chars.length; x++)
{
if((x+1) % 3 == 0)
{
char first = my_chars[x-2];
char second = my_chars[x-1];
char third = my_chars[x];
int first_binary = Integer.parseInt(Integer.toBinaryString(first));
int second_binary = Integer.parseInt(Integer.toBinaryString(second));
int third_binary = Integer.parseInt(Integer.toBinaryString(third));
int n = (((first << 8) | second) << 8) | third;
System.out.print(my_chars[x-2] + "" + my_chars[x-1] + my_chars[x] + Integer.toBinaryString(n));
}
}
System.out.println();
System.out.println(Integer.toBinaryString('s'));
What I'm trying to achieve is to combine those 8 bits from the chars that I get into a big 24 bits int. The problem I'm facing is that the result is a 23 bit int. Say my first 3 chars were:
'T' with a binary representation of 01010100
'u' with a binary representation of 01110101
'r' with a binary representation of 01110010
The result that I get from my program is a int formed from these bits:
10101000111010101110010
Which is missing the 0 at the beginning from the representation of 'T'.
Also I have included the last 2 lines of code because the binary string that I get from 's' is: 1110011 which is missing the 0 at the beginning.
I have checked if I scrolled by mistake to the right but it does not seem that I have done so.
The method Integer.toBinaryString() does not zero-pad the results on the left; you'll have to zero-pad it yourself.
This value is converted to a string of ASCII digits in binary (base 2)
with no extra leading 0s.

having trouble understanding code, specifically the &

I am reading a tutorial regarding a Java pacman game.
Here is the code in question.
if (pacmanx % blocksize == 0 && pacmany % blocksize == 0) {
pos = // integer
ch = screendata[pos];
if ((ch & 16) != 0) { // do not understand this.
screendata[pos] = (short)(ch & 15);
...
}
I am not really understanding the single &. I understand this operand checks both sides of an if statement, or is a bitwise operator. However, per the tests below, it doesn't seem to be either:
if I was to test (ch = 18):
(ch & 16) = 16
(ch & 8) = 0
(ch & 2) = 2
thanks
& is the bitwise operator AND:
18 = 10010
16 = 10000
----------
16 = 10000
18 = 10010
8 = 01000
----------
0 = 00000
So the if will check if the fifth bit is 1 or 0.
That's not a Boolean and, which is always &&; instead it's a bitwise and. It's checking to see if the 5th bit from the right is set in ch.
ch = 18 // ch = 0b00010100
ch & 16 // 16 = 0b00010000
// ch & 16 = 0b00010000 != 0
ch & 8 // 8 = 0b00001000
// ch & 8 = 0b00000000 == 0
ch & 2 // 2 = 0b00000010
// ch & 2 = 0b00000010 != 0
The single & it's a bitwise AND. It's an and operation performed on individual bit of your number.
Consider a possible bit representation of your short:
10011011 & : screendata[pos]
00010000 = : 16
----------
10010000
Specifically this line:
if ((ch & 16) != 0) {
check if the 5-th bit (2^ (5 -1)) of your number is set to 1 (different from 0).
Given ch = 18
(ch & 16) = 16
(ch & 8) = 0
(ch & 2) = 2
seems correct. What's 18 in binary ? 16 | 2 or 10010 in binary.
To be clear, & is a bitwise operator. However && returns true if both operands are true.
Single ampersand is a bitwise AND operator.
You might find it easier to "get" if the values were in hex.
The bitwise and operator & performs an "and" on each bit of the two integers to determine the result.
So:
18 = 0001 0010
16 = 0001 0000
18&16 = 0001 0000
& is bitwise operator AND. You can see detail in http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html

How to find most significant bit (MSB)

I want to know which value the first bit of a byte has.
For example:
I have byte m = (byte) 0x8C;
How could I know if the first bit is an 1 or a 0 ?
Can anyone help me out ?
It depends what you mean by "first bit". If you mean "most significant bit" you can use:
// 0 or 1
int msb = (m & 0xff) >> 7;
Or if you don't mind the values being 0x80 or 0, just use:
// 0 or 0x80
int msb = m & 0x80;
Or in fact, as a boolean:
// Uses the fact that byte is signed using 2s complement
// True or false
boolean msb = m < 0;
If you mean the least significant bit, you can just use:
// 0 or 1
int lsb = m & 1;
If the first bit is the lowest bit (ie bit 0), then
if((m & 1) >0) ...
should do it.
In general,
if ((m & (1<<N)) > 0) ...
will give you whether or not bit N is set.
If, however, you meant the highest bit (bit 7), then use N=7.
Assuming you mean leftmost bit, bitwise and it with 0x80 and check if it is zero nor not:
public boolean isFirstBitSet(byte b) {
System.out.println((b & (byte)0x80));
return (b & (byte)0x80) < 0;
}
If you mean lowest order bit you will need to and with 0x01 and check a different condition:
public boolean isFirstBitSet(byte b) {
System.out.println((b & (byte)0x01));
return (b & (byte)0x80) > 0;
}
Use the bitwise and operator.
public class BitExample {
public static void main(String args[]) throws Exception {
byte m = (byte)0x8C;
System.out.println("The first bit is " + (m & (byte)0x01));
m = (byte)0xFF;
System.out.println("The first bit is " + (m & (byte)0x01));
}
}
// output is...
The first bit is 0
The first bit is 1
Its a bit of a hack but you can use
if(x >> -1 != 0) // top bit set.
This works for byte, short, int, long data types.
However for most types the simplest approach is to compare with 0
if (x < 0) // top bit set.
This works for byte, short, int, long, float, or double
(Ignoring negative zero and negative NaN, most people do ;)
For char type you need to know the number of bits. ;)
if (ch >>> 15 != 0) // top bit set.
This code gives you msb(most significant bit)/biggest number which is a
power of 2 and less than any given number.
class msb{
void main(){
int n=155;//let 110001010
int l=(Integer.toBinaryString(n)).length();//9
String w="0"+Integer.toBinaryString(i).substring(1);//010001010
i=Integer.parseInt(w,2);
System.out.println(n^i);//110001010^010001010=100000000
}
}

Python equivalent to Java's BitSet

Is there a Python class or module that implements a structure that is similar to the BitSet?
There's nothing in the standard library. Try:
http://pypi.python.org/pypi/bitarray
Have a look at this implementation in Python 3.
The implementation basically makes use of the built-in int type, which is arbitrary precision integer type in Python 3 (where long is the Python 2 equivalent).
#! /usr/bin/env python3
"""
bitset.py
Written by Geremy Condra
Licensed under GPLv3
Released 3 May 2009
This module provides a simple bitset implementation
for Python.
"""
from collections import Sequence
import math
class Bitset(Sequence):
"""A very simple bitset implementation for Python.
Note that, like with normal numbers, the leftmost
index is the MSB, and like normal sequences, that
is 0.
Usage:
>>> b = Bitset(5)
>>> b
Bitset(101)
>>> b[:]
[True, False, True]
>>> b[0] = False
>>> b
Bitset(001)
>>> b << 1
Bitset(010)
>>> b >> 1
Bitset(000)
>>> b & 1
Bitset(001)
>>> b | 2
Bitset(011)
>>> b ^ 6
Bitset(111)
>>> ~b
Bitset(110)
"""
value = 0
length = 0
#classmethod
def from_sequence(cls, seq):
"""Iterates over the sequence to produce a new Bitset.
As in integers, the 0 position represents the LSB.
"""
n = 0
for index, value in enumerate(reversed(seq)):
n += 2**index * bool(int(value))
b = Bitset(n)
return b
def __init__(self, value=0, length=0):
"""Creates a Bitset with the given integer value."""
self.value = value
try: self.length = length or math.floor(math.log(value, 2)) + 1
except Exception: self.length = 0
def __and__(self, other):
b = Bitset(self.value & int(other))
b.length = max((self.length, b.length))
return b
def __or__(self, other):
b = Bitset(self.value | int(other))
b.length = max((self.length, b.length))
return b
def __invert__(self):
b = Bitset(~self.value)
b.length = max((self.length, b.length))
return b
def __xor__(self, value):
b = Bitset(self.value ^ int(value))
b.length = max((self.length, b.length))
return b
def __lshift__(self, value):
b = Bitset(self.value << int(value))
b.length = max((self.length, b.length))
return b
def __rshift__(self, value):
b = Bitset(self.value >> int(value))
b.length = max((self.length, b.length))
return b
def __eq__(self, other):
try:
return self.value == other.value
except Exception:
return self.value == other
def __int__(self):
return self.value
def __str__(self):
s = ""
for i in self[:]:
s += "1" if i else "0"
return s
def __repr__(self):
return "Bitset(%s)" % str(self)
def __getitem__(self, s):
"""Gets the specified position.
Like normal integers, 0 represents the MSB.
"""
try:
start, stop, step = s.indices(len(self))
results = []
for position in range(start, stop, step):
pos = len(self) - position - 1
results.append(bool(self.value & (1 << pos)))
return results
except:
pos = len(self) - s - 1
return bool(self.value & (1 << pos))
def __setitem__(self, s, value):
"""Sets the specified position/s to value.
Like normal integers, 0 represents the MSB.
"""
try:
start, stop, step = s.indices(len(self))
for position in range(start, stop, step):
pos = len(self) - position - 1
if value: self.value |= (1 << pos)
else: self.value &= ~(1 << pos)
maximum_position = max((start + 1, stop, len(self)))
self.length = maximum_position
except:
pos = len(self) - s - 1
if value: self.value |= (1 << pos)
else: self.value &= ~(1 << pos)
if len(self) < pos: self.length = pos
return self
def __iter__(self):
"""Iterates over the values in the bitset."""
for i in self[:]:
yield i
def __len__(self):
"""Returns the length of the bitset."""
return self.length
I wouldn't recommend that in production code but for competitive programming, interview preparation and fun, one should make themselves familiar with bit fiddling.
b = 0 # The empty bitset :)
b |= 1 << i # Set
b & 1 << i # Test
b &= ~(1 << i) # Reset
b ^= 1 << i # Flip i
b = ~b # Flip all
You might like to take a look at a module I wrote called bitstring (full documentation here), although for simple cases that need to be as fast as possible I'd still recommend bitarray.
Some similar questions:
What is the best way to do Bit Field manipulation in Python?
Does Python have a bitfield type?
Python Bitstream implementations
If the number of bits is finite, enum.IntFlag can be used as a bit set.
See https://docs.python.org/3/howto/enum.html#intflag

Categories

Resources