retrieve value stored in certain bits of an int - java

We divided an int to save three values into it. For example the first 8 bits (from left to right) hold one value, the 8th to 12th bits hold another value and rest of bits hold the third value.
I am writing a utility method to get value from a certain range of bits of an int. is it good enough? do you have a better solution? The startBitPos and endBitPos are count from right to left.
public static int bitsValue(int intNum, int startBitPos, int endBitPos)
{
//parameters checking ignored for now
int tempValue = intNum << endBitPos;
return tempValue >> (startBitPos + endBitPos);
}
EDIT:
I am sure all values will be unsign.

No, this isn't quite right at the moment:
You should use the unsigned right shift operator to avoid ending up with negative numbers when you don't want them. (That's assuming the original values are unsigned, of course.)
You're not shifting left by the appropriate amount to clear the extraneous high bits.
I suspect you want:
// Clear unnecessary high bits
int tempValue = intNum << (31 - endBitPos);
// Shift back to the lowest bits
return tempValue >>> (31 - endBitPos + startBitPos);
Personally I'd feel more comfortable with a mask-and-shift than this double shifting, but I'm finding it hard to come up with something as short as the above.

public static int bitsValue(int intNum, int startBitPos, int endBitPos)
{
int mask = ~0; //or 0xffffffff
//parameters checking ignored for now
mask = ~(mask<<(endBitPos)) & mask<<startBitPos
return intNum & mask;
}
however if you have commonly used bitranges it's better to keep masks for them statically
0xff000000 // is the 8 most significant bits
0x00e00000 // is the next3 bits and
0x001fffff // are the remaining 21 bits

If you only have a couple of fixed length 'masks' you could store them explicitly and use them like this:
int [] masks = new int [4];
int masks[0] = 0x11111111;
int masks[1] = 0x111100000000;
// ...
public int getValue(int input, int mask){
return input & masks[i];
}

Related

Which one is better amongst right shifting the number and left shifting the bit mask when checking for whether is bit set at the specified position?

I am trying to figure out a problem which asks for checking whether the kth bit is set or not and I have implemented in the following manner using:
Left shift the mask
public static boolean leftShiftingMask(int num, int pos){
return (num & (1 << pos)) != 0;
}
Right shift the number
public static boolean rightShiftingNumber(int num, int pos){
return ((num >> pos) & 1) != 0;
}
Now, in this case both methods have O(1) complexity, but I just want to know that whether left shifting the mask to the desired position is better than right shifting the original number to the desired position or vice-versa is better or both are equivalent?
And one more thing that while checking for whether the bit is set or not, should the position entered by the user should start from 0 or 1, since the place value begins with 2 ^ 0
eg:
binary of 2 is 10 and want to check for 1st bit, then should the kth position be 1st position(i.e. binary 1) or 0th(kth - 1) position(i.e. binary 0)?
You can do it in a way that is much easier to read (to me at least):
public static boolean bitSetOrNot(int num, int pos){
BitSet bitSet = BitSet.valueOf(new long[]{num});
return bitSet.get(pos);
}

What is the fastest way to associate a boolean flag to every possible integer value?

If I had a byte instead of an integer, I could easily create a boolean array with 256 positions and check:
boolean[] allBytes = new boolean[256];
if (allBytes[value & 0xFF] == true) {
// ...
}
Because I have an integer, I can't have an array with size 2 billion. What is the fastest way to check if an integer is true or false? A set of Integers? A hashtable?
EDIT1: I want to associate for every possible integer (2 billion) a true or false flag.
EDIT2: I have ID X (integer) and I need a quick way to know if ID X is ON or OFF.
A BitSet can't handle negative numbers. But there's a simple way around:
class BigBitSet {
private final BitSet[] bitSets = new BitSet[] {new BitSet(), new BitSet()};
public boolean get(int bitIndex) {
return bitIndex < 0 ? bitSets[1].get(~bitIndex)
: bitSets[0].get(bitIndex);
}
...
}
The second BitSet is for negative numbers, which get translated via the '~' operator (that's better than simply negating as it works for Integer.MIN_VALUE, too).
The memory consumption may get up to 4 Gib, i.e., about 524 MB.
I feel stupid for even elaborating on this.
The smallest unit of information your computer can store is a bit, right? A bit has two states, you want two states, so lets just say bit=0 is false and bit=1 is true.
So you need as many bits as there are possible int's, 2^32 = 4,294,967,296. You can fit 8 bits into a byte, so you need only 2^32 / 8 = 536,870,912 bytes.
From that easily follows code to address each of these bits in the bytes...
byte[] store = new byte[1 << 29]; // 2^29 bytes provide 2^32 bits
void setBit(int i) {
int byteIndex = i >>> 3;
int bitMask = 1 << (i & 7);
store[byteIndex] |= bitMask;
}
boolean testBit(int i) {
int byteIndex = i >>> 3;
int bitMask = 1 << (i & 7);
return (store[byteIndex] & bitMask) != 0;
}
java.util.BitSet provides practically the same premade in a nice class, only you can use it to store a maximum of 2^31 bits since it does not work with negative bit indices.
Since you're using Java, use BitSet. It's fast and easy. If you prefer, you could also use an array of primitive longs or BigInteger, but this is really what BitSet is for.
http://docs.oracle.com/javase/7/docs/api/java/util/BitSet.html

How can I extract a particular bit in Java?

I need a specific bit in a byte value stored as int value. My code is as shown below.
private int getBitValue(int byteVal, int bitShift){
byteVal = byteVal << bitShift;
int bit = (int) (byteVal >>>7);
return bit;
}
It is working when I give the bitshift as 1 but when I give the bitshift as 2 and the byteVal as 67(01000011 in binary), I get the value of 'byteVal' as 268 while 'byteVal' should be 3(000011 in binary) after the first line in the method(the left shift). What am I doing wrong here?
For some reason when I try your code I don't get what you get. For your example, if you say byteVal = 0b01000011 and bitShift = 2, then this is what I get:
byteVal = 0b01000011 << 2 = 0b0100001100
bit = (int) (0b0100001100 >>> 7) = (int) (0b010) // redundant cast
returned value: 0b010 == 2
I believe what you intended to do was shift the bit you wanted to the leftmost position, and then shift it all the way to the right to get the bit. However, your code won't do that for a few reasons:
You need to shift left by (variable length - bitShift) to get the desired bit to the place you want. So in this case, what you really want is to shift byteVal left by 6 places, not 2.
int variables are 32 bits wide, not 8. (so you actually want to shift byteVal left by 30 places)
In addition, your question appears to be somewhat contradictory. You state you want a specific bit, yet your example implies you want the bitShift-th least significant bits.
An easier way of getting a specific bit might be to simply shift right as far as you need and then mask with 1: (also, you can't use return with void, but I'm assuming that was a typo)
private int getBitValue(int byteVal, int bitShift) {
byteVal = byteVal >> bitShift; // makes the bitShift-th bit the rightmost bit
// Assumes bit numbers are 0-based (i.e. original rightmost bit is the 0th bit)
return (int) (byteVal & 1) // AND the result with 1, which keeps only the rightmost bit
}
If you want the bitShift-th least significant bits, I believe something like this would work:
private int getNthLSBits(int byteVal, int numBits) {
return byteVal & ((1 << numBits) - 1);
// ((1 << numBits) - 1) gives you numBits ones
// i.e. if numBits = 3, (1 << numBits) - 1 == 0b111
// AND that with byteVal to get the numBits-th least significant bits
}
I'm curious why the answer should be 3 and I think we need more information on what the function should do.
Assuming you want the value of the byteVal's lowest bitShift bits, I'd do the following.
private int getBitValue(int byteVal, int bitShift){
int mask = 1 << bitShift; // mask = 1000.... (number of 0's = bitShift)
mask--; // mask = 000011111 (number of 1's = bitShift)
return (byteVal & mask);
}
At the very least, this function will return 1 for getBitValue(67, 1) and 3 for getBitValue(67,2).

How to get the value of Integer.MAX_VALUE in Java without using the Integer class

I have this question that has completely stumped me.
I have to create a variable that equals Integer.MAX_VALUE... (in Java)
// The answer must contain balanced parentesis
public class Exercise{
public static void main(String [] arg){
[???]
assert (Integer.MAX_VALUE==i);
}
}
The challenge is that the source code cannot contain the words "Integer", "Float", "Double" or any digits (0 - 9).
Here's a succinct method:
int ONE = "x".length();
int i = -ONE >>> ONE; //unsigned shift
This works because the max integer value in binary is all ones, except the top (sign) bit, which is zero. But -1 in twos compliment binary is all ones, so by bit shifting -1 one bit to the right, you get the max value.
11111111111111111111111111111111 // -1 in twos compliment
01111111111111111111111111111111 // max int (2147483647)
As others have said.
int i = Integer.MAX_VALUE;
is what you want.
Integer.MAX_VALUE, is a "static constant" inside of the "wrapper class" Integer that is simply the max value. Many classes have static constants in them that are helpful.
Here's a solution:
int ONE = "X".length();
int max = ONE;
while (max < max + ONE) {
max = max + ONE;
}
or lots of variants.
(The trick you were missing is how to "create" an integer value without using a numeric literal or a number wrapper class. Once you have created ONE, the rest is simple ...)
A bit late, but here goes:
int two = "xx".length();
int thirtyone = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".length();
System.out.println(Math.pow(two, thirtyone)-1);
How did I go? :p
I do like that bitshift one though...
The issue is that the answer cannot contain: "Integer", "Float", "Double", and digits (0 - 9)
There are other things in Java which can be represented as an Integer, for example a char:
char aCharacter = 'a';
int asInt = (int) aCharacter;
System.out.println(asInt); //Output: 97
You can also add chars together in this manner:
char aCharacter = 'a';
char anotherCharacter = 'b';
int sumOfCharacters = aCharacter + anotherCharacter;
System.out.println(sumOfCharacters); //Output: 195
With this information, you should be able to work out how to get to 2147483647on your own.
OK, so an Integer can only take certain values. This is from MIN_VALUE to MAX_VALUE where the minimum value is negative.
If you increase an integer past this upper bound the value will wrap around and become the lowest value possible. e.g. MAX_VALUE+1 = MIN_VALUE.
Equally, if you decrease an integer past the lower bound it will wrap around and become the largest possible value. e.g. MIN_VALUE-1 = MAX_VALUE.
Therefore a simple program that instantiates an int, decrements it until it wraps around and returns that value should give you the same value as Integer.MAX_VALUE
public static void main(String [] arg) {
int i = -1
while (i<0) {
i--;
}
System.out.println(i);
}

Better algorithm for complementing integer value excluding the leading zero binary bits

I will explain first what I mean by "complementing integer value excluding the leading zero binary bits" (from now on, I will call it Non Leading Zero Bits complement or NLZ-Complement for brevity).
For example, there is integer number 92. the binary number is 1011100. If we perform normal bitwise-NOT or Complement, the result is: -93 (signed integer) or 11111111111111111111111110100011 (binary). That's because the leading zero bits are being complemented too.
So, for NLZ-Complement, the leading zero bits are not complemented, then the result of NLZ-complementing of 92 or 1011100 is: 35 or 100011 (binary). The operation is performed by XORing the input value with sequence of 1 bits as much as the non-leading zero value. The illustration:
92: 1011100
1111111 (xor)
--------
0100011 => 35
I had made the java algorithm like this:
public static int nonLeadingZeroComplement(int n) {
if (n == 0) {
return ~n;
}
if (n == 1) {
return 0;
}
//This line is to find how much the non-leading zero (NLZ) bits count.
//This operation is same like: ceil(log2(n))
int binaryBitsCount = Integer.SIZE - Integer.numberOfLeadingZeros(n - 1);
//We use the NLZ bits count to generate sequence of 1 bits as much as the NLZ bits count as complementer
//by using shift left trick that equivalent to: 2 raised to power of binaryBitsCount.
//1L is one value with Long literal that used here because there is possibility binaryBitsCount is 32
//(if the input is -1 for example), thus it will produce 2^32 result whom value can't be contained in
//java signed int type.
int oneBitsSequence = (int)((1L << binaryBitsCount) - 1);
//XORing the input value with the sequence of 1 bits
return n ^ oneBitsSequence;
}
I need an advice how to optimize above algorithm, especially the line for generating sequence of 1 bits complementer (oneBitsSequence), or if anyone can suggest better algorithm?
UPDATE: I also would like to know the known term of this non-leading zero complement?
You can get the highest one bit through the Integer.highestOneBit(i) method, shift this one step left, and then subtract 1. This gets you the correct length of 1s:
private static int nonLeadingZeroComplement(int i) {
int ones = (Integer.highestOneBit(i) << 1) - 1;
return i ^ ones;
}
For example,
System.out.println(nonLeadingZeroComplement(92));
prints
35
obviously #keppil has provided shortest solution. Another solution could be like.
private static int integerComplement(int n){
String binaryString = Integer.toBinaryString(n);
String temp = "";
for(char c: binaryString.toCharArray()){
if(c == '1'){
temp += "0";
}
else{
temp += "1";
}
}
int base = 2;
int complement = Integer.parseInt(temp, base);
return complement;
}
For example,
System.out.println(nonLeadingZeroComplement(92));
Prints answer as 35

Categories

Resources