How to do bitwise unsigned (zero-fill) right shift in Dart? - bit-manipulation

How do I perform bitwise unsigned right shift / zero-fill right shift in Dart?
Something like this for instance:
foo >>> 2

Zero-fill right shift requires a specific integer size. Since integers in Dart are of arbitrary precision the '>>>' operator doesn't make sense there.
The easiest way to emulate a zero-fill right shift is to bit-and the number first.
Example:
(foo & 0xFFFF) >> 2 // 16 bit zero-fill shift
(foo & 0xFFFFFFFF) >> 2 // 32 bit shift.
Update 2021:
Dart integers are now 64 bit. Since Dart 2.14 the >>> operator shifts the 64 bit integer and fills the most significant bits with 0.

The triple-shift operator, i.e. bitwise unsigned right shift of integers has now been added as of Dart 2.14.
Triple-shift >>> operator in Dart
You can simply use this starting with Dart version 2.14:
var foo = 42;
foo >>> 2;
In order to enable this for your app by default, you must upgrade your SDK constraint in pubspec.yaml:
environment:
sdk: '>=2.14.0-0 <3.0.0'
Learn more about the operator in the docs.
Pre Dart 2.14
If you have not yet upgraded to Dart 2.14, you can simply use this function:
/// Bitwise unsigned right shift of [x] by [s] bits.
///
/// This function works as `>>>` does starting with Dart 2.14.
int urs(int x, int s) => s <= 0 ? x : (x >> s) & (0x7fffffffffffffff >> (s - 1));
This works because integers are always 64-bit in Dart nowadays.

You could define a utility function to use:
int zeroFillRightShift(int n, int amount) {
return (n & 0xffffffff) >> amount;
}
That assumes you have 32-bit unsigned integers and that's ok if you do have.

Related

Bits shifted by bit shifting operators(<<, >>) in C, C++

can we access the bits shifted by bit shifting operators(<<, >>) in C, C++?
For example:
23>>1
can we access the last bit shifted(1 in this case)?
No, the shift operators only give the value after shifting. You'll need to do other bitwise operations to extract the bits that are shifted out of the value; for example:
unsigned all_lost = value & ((1 << shift)-1); // all bits to be removed by shift
unsigned last_lost = (value >> (shift-1)) & 1; // last bit to be removed by shift
unsigned remaining = value >> shift; // lose those bits
By using 23>>1, the bit 0x01 is purged - you have no way of retrieving it after the bit shift.
That said, nothing's stopping you from checking for the bit before shifting:
int value = 23;
bool bit1 = value & 0x01;
int shifted = value >> 1;
You can access the bits before shifting, e.g.
value = 23; // start with some value
lsbits = value & 1; // extract the LSB
value >>= 1; // shift
It worth signal that on MSVC compiler an intrinsic function exists: _bittest
that speeds up the operation.

How to set the highest-valued 1 bit to 0 , prefferably in c++ [duplicate]

This question already has answers here:
What's the best way to toggle the MSB?
(4 answers)
Closed 8 years ago.
If, for example, I have the number 20:
0001 0100
I want to set the highest valued 1 bit, the left-most, to 0.
So
0001 0100
will become
0000 0100
I was wondering which is the most efficient way to achieve this.
Preferrably in c++.
I tried substracting from the original number the largest power of two like this,
unsigned long long int originalNumber;
unsigned long long int x=originalNumber;
x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x++;
x >>= 1;
originalNumber ^= x;
,but i need something more efficient.
The tricky part is finding the most significant bit, or counting the number of leading zeroes. Everything else is can be done more or less trivially with left shifting 1 (by one less), subtracting 1 followed by negation (building an inverse mask) and the & operator.
The well-known bit hacks site has several implementations for the problem of finding the most significant bit, but it is also worth looking into compiler intrinsics, as all mainstream compilers have an intrinsic for this purpose, which they implement as efficiently as the target architecture will allow (I tested this a few years ago using GCC on x86, came out as single instruction). Which is fastest is impossible to tell without profiling on your target architecture (fewer lines of code, or fewer assembly instructions are not always faster!), but it is a fair assumption that compilers implement these intrinsics not much worse than you'll be able to implement them, and likely faster.
Using an intrinsic with a somewhat intellegible name may also turn out easier to comprehend than some bit hack when you look at it 5 years from now.
Unluckily, although a not entirely uncommon thing, this is not a standardized function which you'd expect to find in the C or C++ libraries, at least there is no standard function that I'm aware of.
For GCC, you're looking for __builtin_clz, VisualStudio calls it _BitScanReverse, and Intel's compiler calls it _bit_scan_reverse.
Alternatively to counting leading zeroes, you may look into what the same Bit Twiddling site has under "Round up to the next power of two", which you would only need to follow up with a right shift by 1, and a NAND operation. Note that the 5-step implementation given on the site is for 32-bit integers, you would have to double the number of steps for 64-bit wide values.
#include <limits.h>
uint32_t unsetHighestBit(uint32_t val) {
for(uint32_t i = sizeof(uint32_t) * CHAR_BIT - 1; i >= 0; i--) {
if(val & (1 << i)) {
val &= ~(1 << i);
break;
}
}
return val;
}
Explanation
Here we take the size of the type uint32_t, which is 4 bytes. Each byte has 8 bits, so we iterate 32 times starting with i having values 31 to 0.
In each iteration we shift the value 1 by i to the left and then bitwise-and (&) it with our value. If this returns a value != 0, the bit at i is set. Once we find a bit that is set, we bitwise-and (&) our initial value with the bitwise negation (~) of the bit that is set.
For example if we have the number 44, its binary representation would be 0010 1100. The first set bit that we find is bit 5, resulting in the mask 0010 0000. The bitwise negation of this mask is 1101 1111. Now when bitwise and-ing & the initial value with this mask, we get the value 0000 1100.
In C++ with templates
This is an example of how this can be solved in C++ using a template:
#include <limits>
template<typename T> T unsetHighestBit(T val) {
for(uint32_t i = sizeof(T) * numeric_limits<char>::digits - 1; i >= 0; i--) {
if(val & (1 << i)) {
val &= ~(1 << i);
break;
}
}
return val;
}
If you're constrained to 8 bits (as in your example), then just precalculate all possible values in an array (byte[256]) using any algorithm, or just type it in by hand.
Then you just look up the desired value:
x = lookup[originalNumber]
Can't be much faster than that. :-)
UPDATE: so I read the question wrong.
But if using 64 bit values, then break it apart into 8 bytes, maybe by casting it to a byte[8] or overlaying it in a union or something more clever. After that, find the first byte which are not zero and do as in my answer above with that particular byte. Not as efficient I'm afraid, but still it is at most 8 tests (and in average 4.5) + one lookup.
Of course, creating a byte[65536} lookup will double the speed.
The following code will turn off the right most bit:
bool found = false;
int bit, bitCounter = 31;
while (!found) {
bit = x & (1 << bitCounter);
if (bit != 0) {
x &= ~(1 << bitCounter);
found = true;
}
else if (bitCounter == 0)
found = true;
else
bitCounter--;
}
I know method to set more right non zero bit to 0.
a & (a - 1)
It is from Book: Warren H.S., Jr. - Hacker's Delight.
You can reverse your bits, set more right to zero and reverse back. But I do now know efficient way to invert bits in your case.

Implementing logical shifts

I need to implement a bitwise shift (logical, not arithmetic) on OpenInsight 8.
In the system mostly everything is a string but there are 4 functions that treat numbers as 32-bit integers. The bitwise functions available are AND, OR, NOT and XOR. Any arithmetic operators treat the number as signed.
I'm currently having a problem with implementing left and right shifts which I need to implement SHA-1.
Can anyone suggest an algorithm which can help me accomplish this? Pseudocode is good enough, I just need a general idea.
You can implement shifting with integer multiplication and division:
Shift left = *2
Shift right = /2
Perhaps you need to mask the number first to make the most siginificant bit zero to prevent integer overflow.
logical shift down by one bit using signed arithmetic and bitwise ops
if v < 0 then
v = v & 0x7fffffff // clear the top bit
v = v / 2 // shift the rest down
v = v + 0x40000000 // set the penultimate bit
else
v = v / 2
fi
If there's no logical right shift you can easily achieve that by right shifting arithmetically n bits then clear the top n bits
For example: shift right 2 bits:
x >= 2;
x &= 0x3fffffff;
Shift right n bits
x >= n;
x &= ~(0xffffffff << (32 - n));
// or
x >= n;
x &= (1 << (32 - n)) - 1;
For left shifting there's no logical/mathematical differentiation because they are all the same, just shift 0s in.

Set A Float's Fractional Part Using 6 Bits

I am uncompressing some data from double words.
unsigned char * current_word = [address of most significant byte]
My first 14 MSB are an int value. I plan to extract them using a bitwise AND with 0xFFFC.
int value = (int)( (uint_16)current_word & 0xFFFC );
My next 6 bits are a fractional value. Here I am stuck on an efficient implementation. I could extract one bit at a time, and build the fraction 1/2*bit + 1/4+bit + 1/8*bit etc ... but that's not efficient.
float fractional = ?
The last 12 LSB are another int value, which I feel I can pull out using bitwise AND again.
int other_value = (int) ( (uint_16)current_word[2] & 0x0FFF );
This operation will be done on 16348 double words and needs to be finished within 0.05 ms to run at least 20Hz.
I am very new to bit operations, but I'm excited to learn. Reading material and/or examples would be greatly appreciated!
Edit: I wrote OR when I meant AND
Since you're starting with [address of most significant byte] and using increasing addresses from there, your data is apparently in Big-Endian byte order. Casting pointers will therefore fail on nearly all desktop machines, which use Little-Endian byte order.
The following code will work, regardless of native byte order:
int value = (current_word[0] << 6) | (current_word[1] >> 2);
double fractional = (current_word[1] & 0x03) / 4.0 + (current_word[2] & 0xF0) / 1024.0;
int other_value = (current_word[2] & 0x0F) << 8 | current_word[3];
Firstly you'd be more efficient getting the double-word all at once into an int and masking/shifting from there.
Getting the fractional part from that is easy: mask and shift to get an integer, then divide by a float to scale the result.
float fractional = ((current_int >> 12) & 0x3f) / 64.;
there are 5 kinds of shift instructions:
Shift right with sign extend: It will copy your current leftmost bit as the new bit to the leftmost after shifting all the bits to the right. Rightmost one gets dropped.
Shift right with zero extend: Same as (1) but assume that your new leftmost bit is always zero.
Shift left: replace right in (1) and (2) with left , left with right and read (2) again.
Roll right: Shift your bits to the right, instead of rightmost one dropping, it becomes your leftmost.
Roll left: Replace right in (4) with left , left with right and read (4) again.
You can shift as many times you want. In C, more than the amount of bits in your datatype is undefined. Unsigned and signed types shift differently although the syntax is same.
If you are reading your data as unsigned char *, you are not going to be able to get more than 8-bits at a time of data and your example needs to change. If your address is aligned, or your platform allows, you should read your data in as an int *, but then that also begs the question of just how your data is stored. Is it stored 20-bits per integer with 12-bits of other info, or is it a 20-bit stream where you need to keep track of your bit pointer. If the second, it's even more complex than you realize. I'll post further once I have a feel for how your data is laid out in RAM.

binary comparation

Is there any function in c++ to convert decimal number to binary number without using divide algorithm?
I want to count different bits of binary format of 2 numbers. like diff(0,2) is 1 bit. or diff(3,15) is 2 bit.
I want to write diff function.
thanks
You can find the number of different bits by counting the bits in the xor of the two numbers.
Something like this.
int count_bits(unsigned int n) {
int result = 0;
while(n) {
result += 1;
// Remove the lowest bit.
n &= n - 1;
}
return result;
}
int diff(unsigned int a, unsigned int b) {
return count_bits(a ^ b);
}
You can use XOR on the numbers ( if Z = X XOR Y then each bit which is set differently in X and Y will be set to 1 in Z, each bit that is set the same in X and Y will be set to 0), and count the bits of the result using a simple loop and shift.
Everything is already in binary technically. You just need to start looking at bitwise operators to access the individual bits composing the decimal numbers you're looking at.
For example,
if (15 & 1) would check to see if 15 has its first bit turned on.
if (15 & 3) would check to see if its first 2 bits were turned on.
if (15 & 4) would check to see if its 3rd bit only was turned on.
You can do this with and/or/xor/etc. Google bitwise operators and read up.