Taking a natural number a as input, it is easy to read the bits of its binary form from MSB to LSB in O(n) time, n being its binary length, using only a for loop and elementary sums and subtractions. A left shift can be achieved by a+a and subtracting 1000000...
def powerOfTwo(n):
a = 1
for j in range(0,n):
a=(a+a)
return a
def bitLenFast(n):
len=0
if (n==0):
len=1
else:
y=1
while (y<=n):
y=(y+y)
len=(len+1)
return len
def readAsBinary(x):
len=bitLenFast(x) # Length of input x in bits
y=powerOfTwo((len-1)) # Reference word 1000000...
hBit=powerOfTwo(len) # Deletes highest bit in left shift
for i in range(0, len):
if (x>=y):
bit=1
x=((x+x)-hBit)
else:
bit=0
x=(x+x)
print(bit)
Is there an algorithm to parse a bit by bit from LSB to MSB in O(n) time, using only a while or a for loop and elementary operations (i.e. no bitwise built-in functions or operators)?
Apply your algorithm to find the bits in MSB to LSB order to the number. Keep an accumulator A initialized to 0 and a place value variable B initialized to 1. At each iteration, add B to A if the bit is set and then double B by adding it to itself. You also need to keep track of the number of consecutive 0 bits. Initialize a counter C to zero beforehand and at each iteration increment it if the bit is 0 or set to zero otherwise.
At the end you will have the number with the bits reversed in A. You can then output C leading zeros and then apply the algorithm to A to output the bits of the original number in LSB to MSB order.
This is an implementation of samgak's answer in JS, using 2 calls to (an adapted version of) OP's code. Since OP's code is O(n), and all added code is O(1), the result is also O(n).
Therefore, the answer to OP's question is yes.
NOTE: updated to add leading zeroes as per samgak's updated answer.
function read_low_to_high(num, out) {
const acc = {
n: 0, // integer with bits in reverse order
p: 1, // current power-of-two
z: 0, // last run of zeroes, to prepend to result once finished
push: (bit) => { // this is O(1)
if (bit) {
acc.n = acc.n + acc.p;
acc.z = 0;
} else {
acc.z = acc.z + 1;
}
acc.p = acc.p + acc.p;
}
};
// with n as log2(num) ...
read_high_to_low(num, acc); // O(n) - bits in reverse order
for (let i=0; i<acc.z; i++) { // O(n) - prepend zeroes
out.push(0);
}
read_high_to_low(acc.n, out); // O(n) - bits in expected order
}
function read_high_to_low(num, out) {
let po2 = 1; // max power-of-two <= num
let binlength = 1;
while (po2 + po2 <= num) {
po2 = po2 + po2;
binlength ++;
}
const hi = po2 + po2; // min power-of-two > num
for (let i=0; i<binlength; i++) {
if (num>=po2) {
out.push(1);
num = num + num - hi;
} else {
out.push(0);
num = num + num;
}
}
}
function test(i) {
const a = i.toString(2)
.split('').map(i => i-'0');
const ra = a.slice().reverse();
const b = [];
read_high_to_low(i, b);
const rb = [];
read_low_to_high(i, rb);
console.log(i,
"high-to-low",
JSON.stringify(a),
JSON.stringify(b),
"low-to-high",
JSON.stringify(ra),
JSON.stringify(rb)
);
}
for (let i=0; i<16; i++) test(i);
Perhaps you want something like this:
value = 666
while value:
next = value // 2 # integer division
bit = value - next * 2
print(bit, end = " ")
value = next
>>> 0 1 0 1 1 0 0 1 0 1
For reading digits from least significant to most significant and determining the numerical value, there is, but for a valid assertion about run time it would be essential if e.g. indexed access is constant time.
For digits in numerical value:
value ← 0, weight ← 1
foreach digit
while 0 < digit
value ← value + weight
digit ← digit - 1
weight ← weight + weight
Last week I was in an interview and there was a test like this:
Calculate N/9 (given that N is a positive integer), using only
SHIFT LEFT, SHIFT RIGHT, ADD, SUBSTRACT instructions.
first, find the representation of 1/9 in binary
0,0001110001110001
means it's (1/16) + (1/32) + (1/64) + (1/1024) + (1/2048) + (1/4096) + (1/65536)
so (x/9) equals (x>>4) + (x>>5) + (x>>6) + (x>>10) + (x>>11)+ (x>>12)+ (x>>16)
Possible optimization (if loops are allowed):
if you loop over 0001110001110001b right shifting it each loop,
add "x" to your result register whenever the carry was set on this shift
and shift your result right each time afterwards,
your result is x/9
mov cx, 16 ; assuming 16 bit registers
mov bx, 7281 ; bit mask of 2^16 * (1/9)
mov ax, 8166 ; sample value, (1/9 of it is 907)
mov dx, 0 ; dx holds the result
div9:
inc ax ; or "add ax,1" if inc's not allowed :)
; workaround for the fact that 7/64
; are a bit less than 1/9
shr bx,1
jnc no_add
add dx,ax
no_add:
shr dx,1
dec cx
jnz div9
( currently cannot test this, may be wrong)
you can use fixed point math trick.
so you just scale up so the significant fraction part goes to integer range, do the fractional math operation you need and scale back.
a/9 = ((a*10000)/9)/10000
as you can see I scaled by 10000. Now the integer part of 10000/9=1111 is big enough so I can write:
a/9 = ~a*1111/10000
power of 2 scale
If you use power of 2 scale then you need just to use bit-shift instead of division. You need to compromise between precision and input value range. I empirically found that on 32 bit arithmetics the best scale for this is 1<<18 so:
(((a+1)<<18)/9)>>18 = ~a/9;
The (a+1) corrects the rounding errors back to the right range.
Hardcoded multiplication
Rewrite the multiplication constant to binary
q = (1<<18)/9 = 29127 = 0111 0001 1100 0111 bin
Now if you need to compute c=(a*q) use hard-coded binary multiplication: for each 1 of the q you can add a<<(position_of_1) to the c. If you see something like 111 you can rewrite it to 1000-1 minimizing the number of operations.
If you put all of this together you should got something like this C++ code of mine:
DWORD div9(DWORD a)
{
// ((a+1)*q)>>18 = (((a+1)<<18)/9)>>18 = ~a/9;
// q = (1<<18)/9 = 29127 = 0111 0001 1100 0111 bin
// valid for a = < 0 , 147455 >
DWORD c;
c =(a<< 3)-(a ); // c= a*29127
c+=(a<< 9)-(a<< 6);
c+=(a<<15)-(a<<12);
c+=29127; // c= (a+1)*29127
c>>=18; // c= ((a+1)*29127)>>18
return c;
}
Now if you see the binary form the pattern 111000 is repeating so yu can further improve the code a bit:
DWORD div9(DWORD a)
{
DWORD c;
c =(a<<3)-a; // first pattern
c+=(c<<6)+(c<<12); // and the other 2...
c+=29127;
c>>=18;
return c;
}
I was asked this question in a interview, so I don't want the solution, just the guidance regarding how to approach it.
You have been given two numbers low and high. And a random generator which generates 0 and 1. I have to generate a number between low and high using that function.
I can get difference between the two numbers and somehow try to generate a number using bit manipulation. But I am not able to figure out how to do that?
You can do:
range = high - low
find n such that 2^n-1 < range <= 2^n
run the random generator n times to generate an int thanks to its binary representation. Something like 010011010 (= 154 in decimal)
add the obtained number to low to get your final number!
Here's a basic bit-by-bit comparison algorithm that gives a random number between low and high, using a random-bit function:
Decrease high by 1 and increase low by 1 (in case the random bits introduced later all equal those in high or low).
Create booleans high_dec and low_inc to store whether at least one 1 in high has been changed into 0, and at least one 0 in low has been changed into 1, and set both of them to false (these will help avoid the result going out of range).
Compare high and low bit-by-bit from MSB to LSB with these cases:
If you find high:1 and low:1 then store a 1 if low_inc=false or store a random bit otherwise (and update high_dec as necessary).
If you find high:1 and low:0 then store a random bit (and update high_dec or low_inc as necessary).
If you find high:0 and low:1 then store a 0 if high_dec=false or store a 1 if low_inc=false or store a random bit otherwise.
If you find high:0 and low:0 then store a 0 if high_dec=false or store a random bit otherwise (and update low_inc as necessary).
Note that the distribution of the random numbers is only uniform if the lowest possible result is a power of 2, and the range is a power of 2. In all cases the whole range is used, but there may be an emphasis on values near the beginning or end of the range.
function between(a, b) {
var lo = (a + 1).toString(2).split(''), // conversion to bit array because
hi = (b - 1).toString(2).split(''), // there is no bit manipulation in JS
lc = false, // low changed
hc = false, // high changed
result = [];
while (lo.length < hi.length) lo.unshift(0); // add leading zeros to low
for (var i = 0; i < hi.length; i++) { // iterate over bits, msb to lsb
var bit = Math.round(Math.random()); // random bit generator
if (hi[i] == 1) {
if (lo[i] == 1) { // case hi:1 lo:1
if (lc == false) bit = 1
else if (bit == 0) hc = true;
} else { // case hi:1 lo:0
if (bit == 0) hc = true
else lc = true;
}
} else {
if (lo[i] == 1) { // case hi:0 lo:1
if (hc == false) bit = 0
else if (lc == false) bit = 1;
} else { // case hi:0 lo:0
if (hc == false) bit = 0
else if (bit == 1) lc = true;
}
}
result.push(bit);
}
return parseInt(result.join(''), 2); // convert bit array to integer
}
document.write(between(999999, 1000100) + "<BR>");
I'm looking for algorithm working in loop which will generate any natural number n with using only incrementation and multiplication by 2 well trivial way is known (increment number n times) but I'm looking for something a little bit faster. Honestly I don't even know how I should start this.
Basically, what you want to do is shift in the bits of the number from the right, starting with the MSB.
For example, if your number is 70, then the binary of it is 0b1000110. So, you want to "shift in" the bits 1, 0, 0, 0, 1, 1, 0.
To shift in a zero, you simply double the number. To shift in a one, you double the number, then increment it.
if (bit_to_be_shifted_in != 0)
x = (x * 2) + 1;
else
x = x * 2;
So, if you're given an array of bits from MSB to LSB (i.e. from left to right), then the C code looks like this:
x = 0;
for (i = 0; i < number_of_bits; i++)
{
if (bits[i] != 0)
x = x * 2 + 1;
else
x = x * 2;
}
One way of doing this is to go backwards. If it's an odd number, subtract one. If it's even, divide by 2.
while(n > 0) {
n & 1 ? n &= ~1 : n >>= 1;
}
I am trying to find an algorithm to count from 0 to 2n-1 but their bit pattern reversed. I care about only n LSB of a word. As you may have guessed I failed.
For n=3:
000 -> 0
100 -> 4
010 -> 2
110 -> 6
001 -> 1
101 -> 5
011 -> 3
111 -> 7
You get the idea.
Answers in pseudo-code is great. Code fragments in any language are welcome, answers without bit operations are preferred.
Please don't just post a fragment without even a short explanation or a pointer to a source.
Edit: I forgot to add, I already have a naive implementation which just bit-reverses a count variable. In a sense, this method is not really counting.
This is, I think easiest with bit operations, even though you said this wasn't preferred
Assuming 32 bit ints, here's a nifty chunk of code that can reverse all of the bits without doing it in 32 steps:
unsigned int i;
i = (i & 0x55555555) << 1 | (i & 0xaaaaaaaa) >> 1;
i = (i & 0x33333333) << 2 | (i & 0xcccccccc) >> 2;
i = (i & 0x0f0f0f0f) << 4 | (i & 0xf0f0f0f0) >> 4;
i = (i & 0x00ff00ff) << 8 | (i & 0xff00ff00) >> 8;
i = (i & 0x0000ffff) << 16 | (i & 0xffff0000) >> 16;
i >>= (32 - n);
Essentially this does an interleaved shuffle of all of the bits. Each time around half of the bits in the value are swapped with the other half.
The last line is necessary to realign the bits so that bin "n" is the most significant bit.
Shorter versions of this are possible if "n" is <= 16, or <= 8
At each step, find the leftmost 0 digit of your value. Set it, and clear all digits to the left of it. If you don't find a 0 digit, then you've overflowed: return 0, or stop, or crash, or whatever you want.
This is what happens on a normal binary increment (by which I mean it's the effect, not how it's implemented in hardware), but we're doing it on the left instead of the right.
Whether you do this in bit ops, strings, or whatever, is up to you. If you do it in bitops, then a clz (or call to an equivalent hibit-style function) on ~value might be the most efficient way: __builtin_clz where available. But that's an implementation detail.
This solution was originally in binary and converted to conventional math as the requester specified.
It would make more sense as binary, at least the multiply by 2 and divide by 2 should be << 1 and >> 1 for speed, the additions and subtractions probably don't matter one way or the other.
If you pass in mask instead of nBits, and use bitshifting instead of multiplying or dividing, and change the tail recursion to a loop, this will probably be the most performant solution you'll find since every other call it will be nothing but a single add, it would only be as slow as Alnitak's solution once every 4, maybe even 8 calls.
int incrementBizarre(int initial, int nBits)
// in the 3 bit example, this should create 100
mask=2^(nBits-1)
// This should only return true if the first (least significant) bit is not set
// if initial is 011 and mask is 100
// 3 4, bit is not set
if(initial < mask)
// If it was not, just set it and bail.
return initial+ mask // 011 (3) + 100 (4) = 111 (7)
else
// it was set, are we at the most significant bit yet?
// mask 100 (4) / 2 = 010 (2), 001/2 = 0 indicating overflow
if(mask / 2) > 0
// No, we were't, so unset it (initial-mask) and increment the next bit
return incrementBizarre(initial - mask, mask/2)
else
// Whoops we were at the most significant bit. Error condition
throw new OverflowedMyBitsException()
Wow, that turned out kinda cool. I didn't figure in the recursion until the last second there.
It feels wrong--like there are some operations that should not work, but they do because of the nature of what you are doing (like it feels like you should get into trouble when you are operating on a bit and some bits to the left are non-zero, but it turns out you can't ever be operating on a bit unless all the bits to the left are zero--which is a very strange condition, but true.
Example of flow to get from 110 to 001 (backwards 3 to backwards 4):
mask 100 (4), initial 110 (6); initial < mask=false; initial-mask = 010 (2), now try on the next bit
mask 010 (2), initial 010 (2); initial < mask=false; initial-mask = 000 (0), now inc the next bit
mask 001 (1), initial 000 (0); initial < mask=true; initial + mask = 001--correct answer
Here's a solution from my answer to a different question that computes the next bit-reversed index without looping. It relies heavily on bit operations, though.
The key idea is that incrementing a number simply flips a sequence of least-significant bits, for example from nnnn0111 to nnnn1000. So in order to compute the next bit-reversed index, you have to flip a sequence of most-significant bits. If your target platform has a CTZ ("count trailing zeros") instruction, this can be done efficiently.
Example in C using GCC's __builtin_ctz:
void iter_reversed(unsigned bits) {
unsigned n = 1 << bits;
for (unsigned i = 0, j = 0; i < n; i++) {
printf("%x\n", j);
// Compute a mask of LSBs.
unsigned mask = i ^ (i + 1);
// Length of the mask.
unsigned len = __builtin_ctz(~mask);
// Align the mask to MSB of n.
mask <<= bits - len;
// XOR with mask.
j ^= mask;
}
}
Without a CTZ instruction, you can also use integer division:
void iter_reversed(unsigned bits) {
unsigned n = 1 << bits;
for (unsigned i = 0, j = 0; i < n; i++) {
printf("%x\n", j);
// Find least significant zero bit.
unsigned bit = ~i & (i + 1);
// Using division to bit-reverse a single bit.
unsigned rev = (n / 2) / bit;
// XOR with mask.
j ^= (n - 1) & ~(rev - 1);
}
}
void reverse(int nMaxVal, int nBits)
{
int thisVal, bit, out;
// Calculate for each value from 0 to nMaxVal.
for (thisVal=0; thisVal<=nMaxVal; ++thisVal)
{
out = 0;
// Shift each bit from thisVal into out, in reverse order.
for (bit=0; bit<nBits; ++bit)
out = (out<<1) + ((thisVal>>bit) & 1)
}
printf("%d -> %d\n", thisVal, out);
}
Maybe increment from 0 to N (the "usual" way") and do ReverseBitOrder() for each iteration. You can find several implementations here (I like the LUT one the best).
Should be really quick.
Here's an answer in Perl. You don't say what comes after the all ones pattern, so I just return zero. I took out the bitwise operations so that it should be easy to translate into another language.
sub reverse_increment {
my($n, $bits) = #_;
my $carry = 2**$bits;
while($carry > 1) {
$carry /= 2;
if($carry > $n) {
return $carry + $n;
} else {
$n -= $carry;
}
}
return 0;
}
Here's a solution which doesn't actually try to do any addition, but exploits the on/off pattern of the seqence (most sig bit alternates every time, next most sig bit alternates every other time, etc), adjust n as desired:
#define FLIP(x, i) do { (x) ^= (1 << (i)); } while(0)
int main() {
int n = 3;
int max = (1 << n);
int x = 0;
for(int i = 1; i <= max; ++i) {
std::cout << x << std::endl;
/* if n == 3, this next part is functionally equivalent to this:
*
* if((i % 1) == 0) FLIP(x, n - 1);
* if((i % 2) == 0) FLIP(x, n - 2);
* if((i % 4) == 0) FLIP(x, n - 3);
*/
for(int j = 0; j < n; ++j) {
if((i % (1 << j)) == 0) FLIP(x, n - (j + 1));
}
}
}
How about adding 1 to the most significant bit, then carrying to the next (less significant) bit, if necessary. You could speed this up by operating on bytes:
Precompute a lookup table for counting in bit-reverse from 0 to 256 (00000000 -> 10000000, 10000000 -> 01000000, ..., 11111111 -> 00000000).
Set all bytes in your multi-byte number to zero.
Increment the most significant byte using the lookup table. If the byte is 0, increment the next byte using the lookup table. If the byte is 0, increment the next byte...
Go to step 3.
With n as your power of 2 and x the variable you want to step:
(defun inv-step (x n) ; the following is a function declaration
"returns a bit-inverse step of x, bounded by 2^n" ; documentation
(do ((i (expt 2 (- n 1)) ; loop, init of i
(/ i 2)) ; stepping of i
(s x)) ; init of s as x
((not (integerp i)) ; breaking condition
s) ; returned value if all bits are 1 (is 0 then)
(if (< s i) ; the loop's body: if s < i
(return-from inv-step (+ s i)) ; -> add i to s and return the result
(decf s i)))) ; else: reduce s by i
I commented it thoroughly as you may not be familiar with this syntax.
edit: here is the tail recursive version. It seems to be a little faster, provided that you have a compiler with tail call optimization.
(defun inv-step (x n)
(let ((i (expt 2 (- n 1))))
(cond ((= n 1)
(if (zerop x) 1 0)) ; this is really (logxor x 1)
((< x i)
(+ x i))
(t
(inv-step (- x i) (- n 1))))))
When you reverse 0 to 2^n-1 but their bit pattern reversed, you pretty much cover the entire 0-2^n-1 sequence
Sum = 2^n * (2^n+1)/2
O(1) operation. No need to do bit reversals
Edit: Of course original poster's question was about to do increment by (reversed) one, which makes things more simple than adding two random values. So nwellnhof's answer contains the algorithm already.
Summing two bit-reversal values
Here is one solution in php:
function RevSum ($a,$b) {
// loop until our adder, $b, is zero
while ($b) {
// get carry (aka overflow) bit for every bit-location by AND-operation
// 0 + 0 --> 00 no overflow, carry is "0"
// 0 + 1 --> 01 no overflow, carry is "0"
// 1 + 0 --> 01 no overflow, carry is "0"
// 1 + 1 --> 10 overflow! carry is "1"
$c = $a & $b;
// do 1-bit addition for every bit location at once by XOR-operation
// 0 + 0 --> 00 result = 0
// 0 + 1 --> 01 result = 1
// 1 + 0 --> 01 result = 1
// 1 + 1 --> 10 result = 0 (ignored that "1", already taken care above)
$a ^= $b;
// now: shift carry bits to the next bit-locations to be added to $a in
// next iteration.
// PHP_INT_MAX here is used to ensure that the most-significant bit of the
// $b will be cleared after shifting. see link in the side note below.
$b = ($c >> 1) & PHP_INT_MAX;
}
return $a;
}
Side note: See this question about shifting negative values.
And as for test; start from zero and increment value by 8-bit reversed one (10000000):
$value = 0;
$add = 0x80; // 10000000 <-- "one" as bit reversed
for ($count = 20; $count--;) { // loop 20 times
printf("%08b\n", $value); // show value as 8-bit binary
$value = RevSum($value, $add); // do addition
}
... will output:
00000000
10000000
01000000
11000000
00100000
10100000
01100000
11100000
00010000
10010000
01010000
11010000
00110000
10110000
01110000
11110000
00001000
10001000
01001000
11001000
Let assume number 1110101 and our task is to find next one.
1) Find zero on highest position and mark position as index.
11101010 (4th position, so index = 4)
2) Set to zero all bits on position higher than index.
00001010
3) Change founded zero from step 1) to '1'
00011010
That's it. This is by far the fastest algorithm since most of cpu's has instructions to achieve this very efficiently. Here is a C++ implementation which increment 64bit number in reversed patern.
#include <intrin.h>
unsigned __int64 reversed_increment(unsigned __int64 number)
{
unsigned long index, result;
_BitScanReverse64(&index, ~number); // returns index of the highest '1' on bit-reverse number (trick to find the highest '0')
result = _bzhi_u64(number, index); // set to '0' all bits at number higher than index position
result |= (unsigned __int64) 1 << index; // changes to '1' bit on index position
return result;
}
Its not hit your requirements to have "no bits" operations, however i fear there is now way how to achieve something similar without them.