Store array of settings into database row - java

I want to optimize into database row application settings. Something like this
10 - enabled option 1;
12 - enabled option 2;
13 - enabled option 3;
And the entire number is stored into database as 1073741823.
I tried to implement this:
public void test() {
// Let's say you get a String representing your option from your database
String optionFromDB= "132456";
// optionFromDB is a number like "132456"
// We transform it to bigDecimal:
BigDecimal myOptions=new BigDecimal(optionFromDB);
// Then we can use it.
// enable the option X (X is a number)
myOptions.setBit(2);
// Disable option X
myOptions.clearBit(2);
// Save the options to the db:
String newValToSave=myOptions.toString();
// do something if option x enable:
if (myOptions.testBit(123)){
System.out.println("test");
}
}
How I can implement this properly?

Assume value is an integer - this will give you 32 options. If that's not enough, you can take long (64 bits) or apply the same logic to any number of bits.
To enable bit n: value |= 1 <<< n
To disable bit n: value &= ~(1 <<< n)
To test bit n: (value & (1 <<< n)) != 0
To convert to string: String s = Integer.toString(value)
To convert from string: value = Integer.parseInt(s)

Well, just use a number, let's call it state. The type should be decided according to the number of options that you will have. For instance if you have 10 options, Integer is more than enough. For each option you can use one bit of this integer state.
So to set the first option just set first bit, and in general the ith bit for the ith option. To see if the ith option is enabled check if the ith bit of the state is set.
Code key points
For setting the ith bit you can use the following code:
state |= 1 << i;
For testing the ith bit the following:
state & (1L << i)) != 0;
For clearing the ith bit use:
state &= ~(1 << i);

Related

Could someone please explain how shifting is used in this code?

I'm solving sample problems while simultaneously trying to learn Python %\ ... but the problem book I got has problems and solutions in Java, so I'm trying to convert back and forth between the two languages. I just learned how bit shifting works and I've been staring at this code trying to figure out what exactly is going on here on line 5 (and 8) ... I tried writing down some examples just going through the code line by line but for some reason it's still not entirely obvious to me ...
Could someone please clarify?
Also, it's really strange to me that str.charAt(i) returns a character, as far as I understand, and you can then proceed to subtract it from another character like numbers ... Is applying int to a character the same as ord() in Python?
Problem: Implement an algorithm to determine is a string has all unique characters.
Solution (in the case with only characters a-z):
1 boolean isUniqueChars(String str){
2 int checker = 0
3 for (int i = 0; i < str.length(); i++){
4 int val = str.charAt(i) - 'a';
5 if ((checker & (1 << val)) > 0){
6 return false;
7 }
8 checker |= (1 << val);
9 }
10 return true;
11 }
Sure. This code will really only work if str has only lower case letters in it.
checker is a 32-bit integer, and you're using 26 of the 32 bits to record the presence of a particular letter in str. So bit 0 will be used to record the presence of a, bit 1 will be used to record the presence of b, and so on up to bit 25, which will be used to record the presence of z.
The basic algorithm is to work through str, character by character. For each character, find the corresponding bit in checker. If it's already been set, this character must be occurring for the second time - so we can stop processing and return false. Otherwise, set that bit.
If you get to the end of the string without finding any duplicate characters, then return true.
The magic is in the following steps.
Subtracting 'a' from each character converts it to a number from 0 to 25.
The symbol << is the "left shift" operator, which moves a bit pattern a number of bits to the left. The result of this is that 1 << val is the place value of a particular bit (1, 2, 4, 8 etc).
The symbol & does a binary AND, so the expression checker & (1 << val) will be 0 if bit val is cleared, or equal to 1 << val if it is set.
The symbol |= does a binary OR, and assigns the result to the variable on the left. So the expression checker |= (1 << val) sets bit val.
Let's try a simpler variation:
boolean isUniqueChars(String str) {
boolean[] seen = new boolean[26];
for (int i = 0; i < str.length(); i++) {
// convert char to 0-based offset
int index = str.charAt(i) - 'a';
if (seen[index]) {
// this char was seen already
return false;
}
seen[index] = true;
}
// no duplicates found
return true;
}
Pretty straighforward, right? We create a boolean array, using the character offset as an index, and check each character in the string to see if we've come across it yet. The code you posted uses the same logic, but with a more efficient bit set instead.
(1 << val) turns val into a bit index. checker & (1 << val) filters out other indexes so we can check just this one. (checker & (1 << val)) > 0 checks if there's any value at the index. checker |= (1 << val) turns the bit on at the index. All of the other logic is identical.
First, the code will only work reliably if the input string contains letters 'a' to 'z'.
The variable checker is a 32 bit int. Each bit in checker is used as a flag to indicate the presence of one of the 26 letters 'a' to 'z'.
The line
int val = str.charAt(i) - 'a';
converts the character stored at str index i into an integer stored in val, by subtracting the value of character 'a' so. Yes I think pascal has the Ord('') function which does the same.
a = 0
b = 1
c = 2
etc
etc
etc
z = 25
the code
(1 << val)
shifts val into the appropriate value for its bit position,
so
a = 0 = 1
b = 1 = 2
c = 2 = 4
d = 3 = 8
etc
etc
z = 25 = 33554432
if ((checker & (1 << val)) > 0)
determines if the bit is already set in checker, indicating a duplicate character. If so the function returns false.
else
checker |= (1 << val)
sets the bit in checker via a binary OR and then loops round again.

Odd result when bit shifting in Java

I'm trying to isolate two bytes that are next to each other add them, but there seems to be an extra bit that sometimes shows up and I can't figure out how to get rid of it. It's throwing off the answer.
The code is:
(acc & 0x00000000ff000000L) + ((acc << 8) & 0x00000000ff000000L);
and I'm getting results such as
0x0000000147000000
when it should be
0x0000000047000000
How can I get rid of the 1?
Edit: acc is a long. I'm try to add the 5th and 6th byte and then that value will go into a new long in the 5th byte position.
You need to mask the bits you want at the end, because the addition may carry a bit:
((acc & 0x00000000ff000000L) + ((acc << 8) & 0x00000000ff000000L)) & 0x00000000ff000000L;
I think this might be clearer if you broke it down a little:
acc&=0x00000000FFFF000000L; // isolate bytes 5 and 4
acc+=(acc<<8); // add the two bytes (we'll strip bytes 6 & 4 next)
acc&=0x00000000FF00000000L; // reduce to byte 5 only
which happens to be one less bitwise opperation too.
If I understand correctly, you want to get the value of the 5th and 6th byte, add them together, and store them in a new long that contains just that sum in the 5th byte. This would be done like this:
long 5thByte = acc & 0xff00000000 >>> 32;
long 6thByte = acc & 0xff0000000000 >>> 40;
long sum = 5thByte + 6thByte;
long longWithNewByte = sum << 32;
This will of course carryover to the 6th byte if the sum is higher than 255. To get rid of that carryover, you can use another mask.
long longWithNewByte &= 0xff00000000;

Ignoring the first bit using bitwise compare with permission model

I have the bits 101 and 110. I want to compare using some bitwise operator ignoring the first bit like 01 and 10.
Example:
I have:
101
110
===
01 & 10 <- How I want to consider
x00 <- The result I want
or
10110
11011
=====
0110 & 1011 <- How I want to consider
x0010 <- The result I want
How could I achieve this using bitwise operators in java?
Details:
The first bit will always be 1.
The other bits are variable. Both
sides of the comparison will have the same number of bits.
I want to detect just how to make the comparison considering the other bits and
ignoring the first.
Use case:
I have 2 permission values. The first is 5/101 (The permission required) and the second is 6/110 (The permission the user has).
Excluding the first block, which will always be 1, I want to compare the third block that represents a certain permission rule in the system (using bitwise).
"The permission required" bitmask means:
1 - An always fixed value I use to be able to consider the left padding zeroes (unless there is another way to achieve this);
0 - Another permission rule useless for this comparison (let's call permission 1);
1 - The needed permission for the current permission rule (let's call permission 2).
"The permission the user has" means:
1 - A fixed value to be striped out;
1 - Represents the value of the user for the permission 1;
0 - Represents the value of the user for the permission 2. The permission 2 has the value 1 but the user has 0 then he is NOT allowed to the required action. The opposite would be ALLOWED to execute the action.
Any better solution for this case will be considered a correct answer also.
If you know the number of useful bits (e.g numofbits = 5) then the bitmask for the expression is:
bitmask = (1 << numofbits) - 1
If you don't know the numofbits, just make a loop with num = num >> 1, and count the iteration until you got num == 0.
For the use case:
result = (req_roles & user_roles) & (bitmask >> 1)
This simply ands the role bits, ans cuts the upper bit (which is always 1)
Previous answer for previous question :) :
If you know the bitmask for the highest number (e.g. bitmask = 0x1f (11111 in bits)) then you want the result of the following expression:
result = (a ^ b) ^ (bitmask >> 1)
What does it do?
Compares all bits, the equal bits will be 0
Reverts all lower bits, so equal bits will be 1 (leaves the high bit out, so it will remain 0)
Just 'and' the arguments with a mask that has the first bit off, eg 011 & arg before you compare them.
Edit: after restated question.
The alternative is to use role based permissions, these are far more flexible and easier to understand than Boolean permission strings. They are also self documenting. Bit string based permissions are rarely used except where memory or disk space are at a premium, like when Unix was developed back in the early '80s or in embedded systems.
Try this:
// tester 1
int x, y, z, mask;
x = 0x05; // 101
y = 0x06; // 110
mask = getMask(x, y);
z = (mask & (x & y));
System.out.println(String.format("mask: %x result: %x", mask, z));
// tester 2
int x, y, z, mask;
x = 0x16; // 10110
y = 0x1B; // 11011
mask = getMask(x, y);
z = (mask & (x & y));
System.out.println(String.format("mask: %x result: %x", mask, z));
private int getMask(final int x, final int y) {
int mask = findHighOrderOnBit(x, 0);
mask = findHighOrderOnBit(y, mask) - 1;
return mask;
}
private int findHighOrderOnBit(final int target, final int otherMask) {
int result = 0x8000;
for (int x = 0; x != 16; x++) {
if ((result & target) > 0)
break;
result >>= 1;
}
if (otherMask > result)
result = otherMask;
return result;
}

signed to positive near-perfect hash

I have an integer type, say long, whose values are between Long.MIN_VALUE = 0x80...0 (-2^63) and Long.MAX_VALUE = 0x7f...f (2^63 - 1). I want to hash it with ~50% collision to a positive integer of the same type (i.e. between 1 and Long.MAX_VALUE) in a clean and efficient manner.
My first attempts were something like:
Math.abs(x) + 1
(x & Long.MAX_VALUE) + 1
but those and similar approaches always have problems with certain values, i.e. when x is 0 / Long.MIN_VALUE / Long.MAX_VALUE. Of course, the naive solution is to use 2 if statements, but I'm looking for something cleaner / shorter / faster. Any ideas?
Note: Assume that I'm working in Java where there is no implicit conversion to boolean and shift semantics is defined.
The simplest approach is to zero the sign bit and then map zero to some other value:
Long y = x & Long.MAX_VALUE;
return (y == 0)? 42: y;
This is simple, uses only one if/ternary operator, and gives ~50% collision rate on average. There is one disadvantage: it maps 4 different values (0, 42, MIN_VALUE, MIN_VALUE+42) to one value (42). So for this value we have 75% collisions, while for other values - exactly 50%.
It may be preferable to distribute collisions more evenly:
return (x == 0)? 42: (x == Long.MIN_VALUE) ? 142: x & Long.MAX_VALUE;
This code gives 67% collisions for 2 values and 50% for other values. You cannot distribute collisions more evenly, but it is possible to choose these 2 most colliding values. Disadvantage is that this code uses two ifs/ternary operators.
It is possible to avoid 75% collisions on single value while using only one if/ternary operator:
Long y = x & Long.MAX_VALUE;
return (y == 0)? 42 - (x >> 7): y;
This code gives 67% collisions for 2 values and 50% collisions for other values. There is less freedom choosing these most colliding values: 0 maps to 42 (and you can choose almost any value instead); MIN_VALUE maps to 42 - (MIN_VALUE >> 7) (and you can shift MIN_VALUE by any value from 1 to 63, only make sure that A - (MIN_VALUE >> B) does not overflow).
It is possible to get the same result (67% collisions for 2 values and 50% collisions for other values) without conditional operators (but with more complicated code):
Long y = x - 1 - ((x >> 63) << 1);
Long z = y + 1 + (y >> 63);
return z & Long.MAX_VALUE;
This gives 67% collisions for values '1' and 'MAX_VALUE'. If it is more convenient to get most collisions for some other values, just apply this algorithm to x + A, where 'A' is any number.
An improved variant of this solution:
Long y = x + 1 + ((x >> 63) << 1);
Long z = y - (y >> 63);
return z & Long.MAX_VALUE;
Assuming you want to collapse all values into the positive space, why not just zero the sign bit?
You can do this with a single bitwise op by taking advantage of the fact that MAX_VALUE is just a zero sign bit followed by ones e.g.
int positive = value & Integer.MAX_VALUE;
Or for longs:
long positive = value & Long.MAX_VALUE;
If you want a "better" hash with pseudo-random qualities, you probably want to pss the value through another hash function first. My favourite fast hashes are the XORshift family by George Marsaglia. These have the nice property that they map the entire int / long number space perfectly onto itself, so you will still get exactly 50% collisions after zeroing the sign bit.
Here's a quick XORshift implementation in Java:
public static final long xorShift64(long a) {
a ^= (a << 21);
a ^= (a >>> 35);
a ^= (a << 4);
return a;
}
public static final int xorShift32(int a) {
a ^= (a << 13);
a ^= (a >>> 17);
a ^= (a << 5);
return a;
}
I would opt for the most simple, yet not totally time wasting version:
public static long postiveHash(final long hash) {
final long result = hash & Long.MAX_VALUE;
return (result != 0) ? result : (hash == 0 ? 1 : 2);
}
This implementation pays one conditional operation for all but two possible inputs: 0 and MIN_VALUE. Those two are assigned different value mappings with the second condition. I doubt you get a better combination of (code) simplicity and (computational) complexity.
Of course if you can live with a worse distribution, it gets a lot simpler. By restricting the space to 1/4 instead of to 1/2 -1 you can get:
public static long badDistribution(final long hash) {
return (hash & -4) + 1;
}
You can do it without any conditionals and in a single expression by using the unsigned shift operator:
public static int makePositive(int x) {
return (x >>> 1) + (~x >>> 31);
}
If the value is positive, it probably can be used directly, else, invert all bits:
x >= 0 ? hash = x : hash = x ^ Long.MIN_VALUE
However, you should scramble this value a bit more if the values of x are correlated (meaning: similar objects produce similar values for x), maybe with
hash = a * (hash + b) % (Long.MAX_VALUE) + 1
for some positive constants a and b, where a should be quite large and b prevents that 0 is always mapped to 1. This also maps the whole thing to [1,Long.MAX_VALUE] instead of [0,Long.MAX_VALUE]. By altering the values for a and b you could also implement more complex hash functionalities like cooko hashing, that needs two different hash functions.
Such a solution should definitely be preferred instead of one that delivers "strange collision distribution" for the same values each time it is used.
From the information theoretic view, you have 2^64 values to map into 2^63-1 values.
As such, mapping is trivial with the modulus operator, since it always has a non-negative result:
y = 1 + x % 0x7fffffffffffffff; // the constant is 2^63-1
This could be pretty expensive, so what else is possible?
The simple math 2^64 = 2 * (2^63 - 1) + 2 says we will have two source values mapping to one target value except in two special cases, where three will go to one. Think of these as two special 64-bit values, call them x1 and x2, that each share a target with two other source values. In the mod expression above, this occurs by "wrapping". The target values y=2^31-2 and y=2^31-3 have three mappings. All others have two. Since we have to use something more complex than mod anyway, let's seek a way to map the special values wherever we like at low cost
For illustration let's work with mapping a 4-bit signed int x in [-8..7] to y in [1..7], rather than the 64-bit space.
An easy course is to have x values in [1..7] map to themselves, then the problem reduces to mapping x in [-8..0] to y in [1..7]. Note there are 9 source values here and only 7 targets as discussed above.
There are obviously many strategies. At this point you can probably see a gazzilion. I'll describe only one that's particularly simple.
Let y = 1 - x for all values except special cases x1 == -8 and x2 == -7. The whole hash function thus becomes
y = x <= -7 ? S(x) : x <= 0 ? 1 - x : x;
Here S(x) is a simple function that says where x1 and x2 are mapped. Choose S based on what you know about the data. For example if you think high target values are unlikely, map them to 6 and 7 with S(x) = -1 - x.
The final mapping is:
-8: 7 -7: 6 -6: 7 -5: 6 -4: 5 -3: 4 -2: 3 -1: 2
0: 1 1: 1 2: 2 3: 3 4: 4 5: 5 6: 6 7: 7
Taking this logic up to the 64-bit space, you'd have
y = (x <= Long.MIN_VALUE + 1) ? -1 - x : x <= 0 ? 1 - x : x;
Many other kinds of tuning are possible within this framework.
Just to make sure, you have a long and want to hash it to an int?
You could do...
(int) x // This results in a meaningless number, but it works
(int) (x & 0xffffffffl) // This will give you just the low order bits
(int) (x >> 32) // This will give you just the high order bits
((Long) x).hashcode() // This is the high and low order bits XORed together
If you want to keep a long you could do...
x & 0x7fffffffffffffffl // This will just ignore the sign, Long.MIN_VALUE -> 0
x & Long.MAX_VALUE // Should be the same I think
If getting a 0 is no good...
x & 0x7ffffffffffffffel + 1 // This has a 75% collision rate.
Just thinking out loud...
((x & Long.MAX_VALUE) << 1) + 1 // I think this is also 75%
I think you're going to need to either be ok with 75% or get a little ugly:
(x > 0) ? x : (x < 0) ? x & Long.MAX_VALUE : 7
This seems the simplest of all:
(x % Long.MAX_VALUE) + 1
I would be interested in speed comparisons of all the methods given.
Just AND your input value with Long.MAX_VALUE and OR it with 1. Nothing else needed.
Ex:
long hash = (input & Long.MAX_VALUE) | 1;

Removing lowest order bit

Given a binary number, what is the fastest way of removing the lowest order bit?
01001001010 -> 01001001000
It would be used in code to iterate over the bits of a variable. Pseudo-code follows.
while(bits != 0){
index = getIndexOfLowestOrderBit(bits);
doSomething(index);
removeLowestOrderBit(bits);
}
The possible languages I'm considering using are C and Java.
This is what I've got so far, I'm wondering if anyone can beat this.
bits &= bits-1
Uh ... In your example, you already know the bit's index. Then it's easy:
bits &= ~(1 << index);
This will mask off the bit whose index is index, regardless of its position in the value (highest, lowest, or in-between). Come to think of it, you can of course use the fact that you know the bit is already set, and use an XOR to knock it clear again:
bits ^= (1 << index);
That saves the inversion, which is probably one machine instruction.
If you instead want to mask off the lowest set bit, without knowing its index, the trick is:
bits &= (bits - 1);
See here for instance.
You can find the lowest set bit using x & (~x + 1). Example:
x: 01101100
~x+1: 10010100
--------
00000100
Clearing the lowest set bit then becomes x & ~(x & (~x + 1)):
x: 01101100
~(x&(~x+1)): 11111011
--------
01101000
Or x & (x - 1) works just as well and is easier to read.
The ever-useful Bit Twiddling Hacks has some algorithms for counting zero bits - that will help you implement your getIndexOfLowestOrderBit function.
Once you know the position of the required bit, flipping it to zero is pretty straightforward, e.g. given a bit position, create mask and invert it, then AND this mask against the original value
result = original & ~(1 << pos);
You don't want to remove the lowest order bit. You want to ZERO the lowest order SET bit.
Once you know the index, you just do 2^index and an exclusive or.
In Java use Integer.lowestOneBit().
I don't know if this is comparable fast, but I think it works:
int data = 0x44A;
int temp;
int mask;
if(data != 0) { // if not there is no bit set
temp = data;
mask = 1;
while((temp&1) == 0) {
mask <<= 1;
temp >>= 1;
}
mask = ~mask;
data &= mask;
}

Categories

Resources