Alt answer to classic bitwise 2^n test: valid? - bit-manipulation

Quick question: I posed the single-line expression to test n for the format 2^n (n>=0).
See: http://www.exploringbinary.com/ten-ways-to-check-if-an-integer-is-a-power-of-two-in-c/
A colleague came up with this unorthodox answer:
((n-1) xor n == 2*n - 1) && (n != 0)
I built a test harness to check it, and it appears to be correct. I tested up to approx. n=10000.
Does anybody see a problem with this solution? I can't find a reference to it online.
Thanks!
-David

You should really test for all inputs (for example by using an SMT solver).
There are 31 cases in which this formula gives true even though n is not a power of two. They are cases where the top bit is set, in addition to some other bit. For example, 0xC0000000 or 0x80000001.
n ^ (n - 1) is a known way to "extract the rightmost set bit and smear it to the right". n * 2 - 1 is accidentally the same in the cases I described, the upper bit is shifted out and the -1 smears the rightmost bit to the right (because the bit is now one to the left of where it used to be).

Related

do this binary numbers have a specific name or property to get them?

i want binary number that only have 0's at the beginning or end, for instance,
1111111
01111110
001111111
000111000
but no:
01001
0011101
do they have an specific name or property to get them?
I'm looking for something like linear integer optimization conditions, my solutions must have this form, but i can't think of any condition i can add to ensure that
Regards,
This is something which is not nice to formulate within mixed-integer programs. Most problems involving this are more suitable for alternative methods (SAT-solving, SMT-solving, Constraint-programming).
It can be done of course, but the solver will have some work as the formulation is non-trivial and introduces a lot of binary-variables (and the basic approach of MIP-solvers won't work amazingly here; bad integrality-gap).
I won't give you a complete solution, but some basic idea on how to formulate this and i also indicate how hard and cumbersome it is (there are alternative formulations; actually infinite many; but nothing much more simple).
The basic idea here is the following:
your binary number is constructed from N binary-variables
let's call them x
you introduce N auxiliary binary-variables l (left)
l[i] == 1 implicates: every l[j] with i<j is 0
you introduce N auxiliary binary-variables r (right)
r[i] == 1 implicates: every r[j] with i>j is 0
you add the following constraint for each position k:
x[k] == 0 implicates: l[i] == 1 for i < k OR r[i] == 1 for i>k
idea::
if there is a zero somewhere, either all on the left-side or all on the right-side are zeroes (or means: at least one side; but can be both)
To formulate this, you need two more ideas:
A: How to formulate the equality-check?
B: How to formulate the implication?
Remark: a -> b == not a or b (propositional calculus)
(this was wrongly stated earlier and corrected by OP)
These are common in MIP and you will find the solution in many integer-programming books, tutorial and papers. Here is an example (start with indicator-variables).
Another small common formulation:
if a is binary, b is binary:
a OR b is equivalent to: a+b >= 1 (the latter is a linear-expression ready to use for MIP)
Remark: The formulas in my idea-setting above might be wrong in regards to indices (i vs. i-1, vs. i+1) and binary-relations (<vs. <=). You will need to do the actual math yourself and just learn from the idea itself!
Remark 2: This kind of constraint is cumbersome in MIP, but more easily formulated within SAT and CP.

Bitwise AND and order of operations in C/C++

I'm currently dissecting through the ol' Doom engine source code, and came across an interesting line:
counter = (++counter)&(MAX_VALUE-1);
Looks like a way to increment a counter without going over a certain number, but I have a tricky time doing bitwise operations in my head so I whipped up a quick console project to try this out, and lo and behold, it works beautifully. I deduce the above way is more efficient than an if() statement, especially if the code is executed rapidly, for example, within a loop, where performance within a real-time game is crucial. What I'm trying to figure out is the order of operations the compiler uses to execute this line. If the increment '++' operator is placed after the 'counter', it will always remain zero. It only works if the increment is used as a prefix ("++counter"), but even still, if I write it out with pen and paper, I get the arbitrary result of the bitwise AND operation, not a counter that increments. It seems the bitwise operation is calculated, and THEN the increment is performed, but I'm stumped figuring out why, any ideas?
While the parentheses have higher precedence than operator ++ or bitwise AND (operator &), there are no defined sequence points in your right-hand side. So your code exhibits undefined behavior.
If you remove the operator++ what this is intending to do is
(counter + 1)&(MAX_VALUE-1);
If you consider MAX_VALUE to be 32 then MAX_VALUE-1 in binary is
11111
So if you have a larger value than that and use & any bits left of bit 5 (from the right) will be cleared
0000011111 // assume this is MAX_VALUE - 1
1100110110 // assume this is counter + 1
__________
0000010110
The result would be true if any of the bits less than or equal to MAX_VALUE - 1 were 1.
The formula
counter = (++counter)&(MAX_VALUE-1);
has undefined behaviour, see CoryKramer's answer.
The formula
counter = (counter + 1)&(MAX_VALUE - 1);
works only for MAX_VALUEs that are equal to a power of 2. Only then the value MAX_VALUE - 1 has this form in binary:
000...000111...111
When such a value is used in a AND operation, it "truncates" the higher bits of the other value, and has the effect of wrapping around when the other value reaches MAX_VALUE.
I think the normal modulo operation is just as fast on modern hardware, and does not have the restriction mentionend above:
counter = (counter + 1)%MAX_VALUE;

pseudo random distribution which guarantees all possible permutations of value sequence - C++

Random question.
I am attempting to create a program which would generate a pseudo-random distribution. I am trying to find the right pseudo-random algorithm for my needs. These are my concerns:
1) I need one input to generate the same output every time it is used.
2) It needs to be random enough that a person who looks at the output from input 1 sees no connection between that and the output from input 2 (etc.), but there is no need for it to be cryptographically secure or truly random.
3)Its output should be a number between 0 and (29^3200)-1, with every possible integer in that range a possible and equally (or close to it) likely output.
4) I would like to be able to guarantee that every possible permutation of sequences of 410 outputs is also a potential output of consecutive inputs. In other words, all the possible groupings of 410 integers between 0 and (29^3200)-1 should be potential outputs of sequential inputs.
5) I would like the function to be invertible, so that I could take an integer, or a series of integers, and say which input or series of inputs would produce that result.
The method I have developed so far is to run the input through a simple halson sequence:
boost::multiprecision::mpz_int denominator = 1;
boost::multiprecision::mpz_int numerator = 0;
while (input>0) {
denominator *=3;
numerator = numerator * 3 + (input%3);
input = input/3;
}
and multiply the result by 29^3200. It meets requirements 1-3, but not 4. And it is invertible only for single integers, not for series (since not all sequences can be produced by it). I am working in C++, using boost multiprecision.
Any advice someone can give me concerning a way to generate a random distribution meeting these requirements, or just a class of algorithms worth researching towards this end, would be greatly appreciated. Thank you in advance for considering my question.
----UPDATE----
Since multiple commenters have focused on the size of the numbers in question, I just wanted to make clear that I recognize the practical problems that working with such sets poses but in asking this question I'm interested only in the theoretical or conceptual approach to the problem - for example, imagine working with a much smaller set of integers like 0 to 99, and the permutations of sets of 10 of output sequences. How would you design an algorithm to meet these five conditions - 1)input is deterministic, 2)appears random (at least to the human eye), 3)every integer in the range is a possible output, 4)not only all values, but also all permutations of value sequences are possible outputs, 5)function is invertible.
---second update---
with many thanks to #Severin Pappadeux I was able to invert an lcg. I thought I'd add a little bit about what I did to hopefully make it easier for anyone seeing this in the future. First of all, these are excellent sources on inverting modular functions:
https://www.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/modular-inverses
https://www.khanacademy.org/computer-programming/discrete-reciprocal-mod-m/6253215254052864
If you take the equation next=ax+c%m, using the following code with your values for a and m will print out the euclidean equations you need to find ainverse, as well as the value of ainverse:
int qarray[12];
qarray[0]=0;
qarray[1]=1;
int i =2;
int reset = m;
while (m % a >0) {
int remainder=m%a;
int quotient=m/a;
std::cout << m << " = " << quotient << "*" << a << " + " << remainder << "\n";
qarray[i] =qarray[i-2]-(qarray[i-1]*quotient);
m=a;
a=remainder;
i++;
}
if (qarray[i-1]<0) {qarray[i-1]+=reset;}
std::cout << qarray[i-1] << "\n";
The other thing it took me a while to figure out is that if you get a negative result, you should add m to it. You should add a similar term to your new equation:
prev = (ainverse(next-c))%m;
if (prev<0) {prev+=m;}
I hope that helps anyone who ventures down this road in the future.
Ok, I'm not sure if there is a general answer, so I would concentrate on random number generator having, say, 64bit internal state/seed, producing 64bit output and having 2^64-1 period. In particular, I would look at linear congruential generator (aka LCG) in the form of
next = (a * prev + c) mod m
where a and m are primes to each other
So:
1) Check
2) Check
3) Check (well, for 64bit space of course)
4) Check (again, except 0 I believe, but each and every permutation of 64bits is output of LCG starting with some seed)
5) Check. LCG is known to be reversible, i.e. one could get
prev = (next - c) * a_inv mod m
where a_inv could be computed from a, m using Euclid's algorithm
Well, if it looks ok to you, you could try to implement LCG in your 15546bits space
UPDATE
And quick search shows reversible LCG discussion/code here
Reversible pseudo-random sequence generator
In your update, "appears random (to the human eye)" is the phrasing you use. The definition of "appears random" is not a well agreed upon topic. There are varying degrees of tests for "randomness."
However, if you're just looking to make it appear random to the human eye, you can just use ring multiplication.
Start with the idea of generating N! values between 0 and M (N>=410, M>=29^3200)
Group this together into one big number. we're going to generate a single number ranging from 0 to *M^N!. If we can show that the pseudorandom number generator generates every value from 0 to M^N!, we guarantee your permutation rule.
Now we need to make it "appear random." To the human eye, Linear Congruent Generators are enough. Pick a LCG with a period greater than or equal to 410!*M^N satisfying the rules to ensure a complete period. Easiest way to ensure fairness is to pick a LCG in the form x' = (ax+c) mod M^N!
That'll do the trick. Now, the hard part is proving that what you did was worth your time. Consider that the period of just a 29^3200 long sequence is outside the realm of physical reality. You'll never actually use it all. Ever. Consider that a superconductor made of Josephine junctions (10^-12kg processing 10^11bits/s) weighing the mass of the entire universe 3*10^52kg) can process roughly 10^75bits/s. A number that can count to 29^3200 is roughly 15545 bits long, so that supercomputer can process roughly 6.5x10^71 numbers/s. This means it will take roughly 10^4600s to merely count that high, or somewhere around 10^4592 years. Somewhere around 10^12 years from now, the stars are expected to wink out, permanently, so it could be a while.
There are M**N sequences of N numbers between 0 and M-1.
You can imagine writing all of them one after the other in a (pseudorandom) sequence and placing your read pointer randomly in the resulting loop of N*(M**N) numbers between 0 and M-1...
def output(input):
total_length = N*(M**N)
index = input % total_length
permutation_index = shuffle(index / N, M**N)
element = input % N
return (permutation_index / (N**element)) % M
Of course for every permutation of N elements between 0 and M-1 there is a sequence of N consecutive inputs that produces it (just un-shuffle the permutation index). I'd also say (just using symmetry reasoning) that given any starting input the output of next N elements is equally probable (each number and each sequence of N numbers is equally represented in the total period).

My code works, but I'm not satisfied with the efficiency. (C++ int to binary to scaled double)

Code pasted here
Hello SO. I just wrote my first semi-significant PC program, written purely for fun/to solve a problem, having not been assigned the problem in a programming class. I'm sure many of you remember the first significant program that you wrote for fun.
My issue is, I am not satisfied with the efficiency of my code. I'm not sure if it's the I/O limitation of my terminal or my code itself, but it seems to run quite slow for DAC resolutions of 8 bits or higher.
I haven't commented the code, so here is an explanation of the problem that I was attempting to solve with this program:
The output voltage of a DAC is determined by a binary number having bits Bn, Bn-1 ... B0, and a full-scale voltage.
The output voltage has an equation of the form:
Vo = G( (1/(2^(0)))*(Bn) + (1/2^(0+1))*(Bn-1) + ... + (1/2^(0+n))*(B0) )
Where G is the gain that would make an input B of all bits high the full-scale voltage.
If you run the code the idea will be quite clear.
My issue is, I think that what I'm outputting to the console can be achieved in much less than 108 lines of C++. Yes, it can easily be done by precomputing the step voltage and simply rendering the table by incrementation, but a "self-requirement" that I have for this program is that on some level it performs the series calculation described above for each binary represented input.
I'm not trying to be crazy with that requirement. I'd like this program to prove the nature of the formula, which it currently does. What I'm looking for is some suggestions on how to make my implementation generally cleaner and more efficient.
pow(2.0, x) is almost always a bad idea - especially if you're iterating over x. pow(2.0,0) == 1, and pow(2.0,x) == 2 * pow(2.0,x-1)
DtoAeqn returns an unbalanced string (one more )), that hurts my brain.
You could use Horner's method to evaluate the formula efficiently. Here's an example I use to demonstrate it for converting binary strings to decimal:
0.1101 = (1*2-1 + 1*2-2 + 0*2-3 + 1*2-4).
To evaluate this expression efficiently, rewrite the terms from right to left, then nest and evaluate as follows:
(((1 * 2-1 + 0) * 2-1 + 1) * 2-1 + 1) * 2-1 = 0.8125.
This way, you've removed the "pow" function, and you only have to do one multiplication (division) for each bit.
By the way, I see your code allows up to 128 bits of precision. You won't be able to compute that accurately in a double.

make an integer even

Sometimes I need to be sure that some integer is even. As such I could use the following code:
int number = /* magic initialization here */;
// make sure the number is even
if ( number % 2 != 0 ) {
number--;
}
but that does not seem to be very efficient the most efficient way to do it, so I could do the following:
int number = /* magic initialization here */;
// make sure the number is even
number &= ~1;
but (besides not being readable) I am not sure that solution is completely portable.
Which solution do you think is best?
Is the second solution completely portable?
Is the second solution considerably faster that the first?
What other solutions do you know for this problem?
What if I do this inside an inline method? It should (theoretically) be as fast as these solutions and readability should no longer be an issue, does that make the second solution more viable?
note: This code is supposed to only work with positive integers but having a solution that also works with negative numbers would be a plus.
Personally, I'd go with an inline helper function.
inline int make_even(int n)
{
return n - n % 2;
}
// ....
int m = make_even(n);
Before accepting an answer I will make my own that tries to summarize and
complete some of the information found here:
Four possible methods where described (and some small variations of these).
if (number % 2 != 0) {
number--;
}
number&= ~1
number = number - (number % 2);
number = (number / 2) * 2;
Before proceeding any further let me clarify something:
The expected gain for using any of these methods is minimal, even if we could
prove that one method is 200% faster than the others the worst one is so fast
that the only way to have visible gain in speed would be if this method was
called many times in a CPU bound application. As such this is more of an
exercise for fun than a real optimization.
Analysis
Readability
As far as readability goes I would rank method 1 as the most readable,
method 4 as the second best and method 2 as the worse.
People are free to disagree but I ranked them like this because:
In method 1 it is as explicit as possible that if the number is odd you
want to subtract from it making it even.
Method 4 is also very much explicit but I ranked it second because at
first glance you might think it is doing nothing, and only a fraction of a
second latter you're like "Oh... Integer division.".
Method 2 and 3 are almost equivalent in terms of readability, but many
people are not used to bitwise operations and as such I ranked method 2 as
the worse.
With that in mind I would add that it is generally accepted that the best way
to implement this is using an inline function, and none of the options is
that unreadable, readability is not really an issue (direct uses in the code
are explicit and clear and reading the method will never be that hard).
If you don't want to use an inline method I would recommend that you only use
method 1 or method 4.
Compatibility issues
Underflow
It has been mentioned that method 1 may underflow, depending on the way the
processor represents integers. Just to be sure you can add the following
STATIC_ASSERT when using method 1.
STATIC_ASSERT(INT_MIN % 2 == 0, make_even_may_underflow);
As for method 3, even when INT_MIN is not even it may not underflow
depending on whether the result has the same sign of the divisor or the
dividend. Having the same sign of the divisor never underflows because
INT_MIN - (-1) is closer to 0.
Add the following STATIC_ASSERT just to be sure:
STATIC_ASSERT(INT_MIN % 2 == 0 || -1 % 2 < 0, make_even_may_underflow);
Of course you can still use these methods when the STATIC_ASSERT fails since
it would only be a problem when you pass INT_MIN to your make_even method,
but I would STRONGLY advice against it.
(Un)supported bit representations
When using method 2 you should make sure your compiler bit representation
behaves as expected:
STATIC_ASSERT( (1 & ~1) == 0, unsupported_bit_representation);
// two's complement OR sign-and-magnitude.
STATIC_ASSERT( (-3 & ~1) == -4 || (-3 & ~1) == -2 , unsupported_bit_representation);
Speed
I also did some naive speed tests using the Unix time utility. I ran every
different method (and its variations) 4 times and recorded the results,
since the results didn't vary much I didn't find necessary to run more tests.
The obtained results show method 4 and method 2 as the fastest of them
all.
Conclusion
According to the provided information, I would recommend using method 4. Its
readable, I am not aware of any compatibility issues and performs great.
I hope you enjoy this answer and use the information contained here to make
your own informed choice. :)
The source code is available if you want to check my results. Please note
that the tests where compiled using g++ and run in Mac OS X. Different
platforms and compilers may give different results.
int even_number = (number / 2) * 2;
This should work regardless architecture as long as optimizer is not going in the way (it shouldn't but who knows).
I would use the second solution. In any binary representation, regardless of the number of bits, big-endian vs. little-endian, or other architecture differences, that operation will have the effect of setting the lowest bit to zero. It's fast and completely portable. The intent of the code can be explained via comments, if you meet any poor C programmers who can't figure out what it means.
The &= solution looks best to me. If you want to make it more portable and more readable:
const int MakeEven = -2;
int number = /* magic initialization here */
// Make sure number is even
number &= MakeEven;
The second solution should be considerably faster than the first. Is it completely portable? Most likely, although there's probably some computer somewhere that does math differently.
This should work for positive and negative integers.
Use your second solution as inline function and put static assert into implementation of it to document and test that it works on platform that it is compiled on.
BOOST_STATIC_ASSERT( (1 & ~1) == 0 );
BOOST_STATIC_ASSERT( (-1 & ~1) == -2 );
Your second solution only works if your sign representation is "two's complement" or "sign and magnitude". To do it in place I'd go with suszterpatt's variant, which should (almost) always work
number -= (number % 2);
You don't know for sure in which direction this will "round" for negative values, so in extreme cases you might have an underflow.
even_integer = (any_integer >> 1) << 1;
This solution achieves the goal in the most performant way compared to the other suggested solutions.
In general, bitwise shift is the cheapest possible operation. Some compilers generate the same assembly for "number = (number / 2) * 2" as well but that is not guaranteed on all target platforms and programming languages.
The following approach is simple and requires no multiplication or division.
number = number & ~1;
or
number = (number + 1) & ~1;