Fastest way to loop every number with conditions - c

Given a 64 bit integer, where the last 52 bits to be evaluated and the leading 12 bits are to be ignored, what is the fastest way to loop every single combination of 7 bits on and all other bits off?
Example:
First permutation:
0[x57]1111111
Last permutation
00000000000011111110[x45]
Where 0[xn] means n off (zero) bits.
Speed is absolutely crucial, we are looking to save every clock cycle we can as it is part of a greater solution that needs to evaluate billions of states in a reasonable amount of time.
A working solution is not required, but some pseudo code would do just fine :)

I think you'll be interested in this article: http://realtimecollisiondetection.net/blog/?p=78
It solves your problem in very efficient way.

What you need is a good algorithm that will take you from one permutation to the next in minimal time.
Now, the first algorithm that comes to mind is to go through all combinations with seven loops.
The first loop goes through the 52 bits, setting one for the next loop.
The second loop goes through the bits after the set one, setting one for the third loop.
...ect
This will give you the fastest iteration. Here is some pseudo C++ code:
__int64 deck;
int bit1, bit2, bit3, ...;
for (bit1=0;bit1<52-6;bit1++) {
for (bit2=bit1+1;bit2<52-5;bit2++) {
...
for (bit7=bit6+1;bit7<52;bit7++) {
deck = (1<<bit1)+(1<<bit2)+(1<<bit3)+...; // this could be optimized.
// do whatever with deck
}
...
}
}
// note: the 52-6, 52-5, will be pre-calculated by the compiler and are there for convenience. You don't have to worry about optimizing this.
There is your solution right there. If you want to check that it works, I always downscale it. For example, following that algorithm on a 4bit number where you need to set 2 bits would go like this:
1100
1010
1001
0110
0101
0011

I think there is a relationship between each permutation.
We can see the number increases with permutation # with a pattern.
This maths isn't correct for all solutions, but works for some, hopefully indicating what I mean:
Permutation 3 difference = ((3%7+1)^2) * (roundUp(3/7) = 16
Permutation 10 difference = ((10%7+1)^2) * (roundUp(10/7) = 32
So we would loop from the absolute values:
int perm = 1;
for int64 i = 127; perm < totalPermutations
{
i = i + ((perm%7+1)^2) * (roundUp(perm/7);
perm++;
}
Again the maths is wrong, but gives an idea, I am sure it is possible to come up with a formula for this. As to whether it outperforms bitwise operations would have to be tested.

Related

PID implementation in arduino

I came across some code online in which the PID is implemented for arduino. I am confused of the implementation. I have basic understanding of how PID works, however my source of confusion is why the hexadecimal is being used for m_prevError? what is the value 0x80000000L representing and why is right shifting by 10 when calculating the velocity?
// ServoLoop Constructor
ServoLoop::ServoLoop(int32_t proportionalGain, int32_t derivativeGain)
{
m_pos = RCS_CENTER_POS;
m_proportionalGain = proportionalGain;
m_derivativeGain = derivativeGain;
m_prevError = 0x80000000L;
}
// ServoLoop Update
// Calculates new output based on the measured
// error and the current state.
void ServoLoop::update(int32_t error)
{
long int velocity;
char buf[32];
if (m_prevError!=0x80000000)
{
velocity = (error*m_proportionalGain + (error - m_prevError)*m_derivativeGain)>>10;
m_pos += velocity;
if (m_pos>RCS_MAX_POS)
{
m_pos = RCS_MAX_POS;
}
else if (m_pos<RCS_MIN_POS)
{
m_pos = RCS_MIN_POS;
}
}
m_prevError = error;
}
Shifting a binary number to right by 1 means multiplying its corresponding decimal value by 2. Here shifting by 10 means multiplying by 2^10 which is 1024. As any basic control loop, it could be a gain of the velocity where the returned-back value is converted to be suitable to re-use by any other method.
The L here 0x80000000L is declaring that value as long. So, this value 0x80000000 may be an initial value of error or so. Also, you need to revise the full program to see how things work and what value is assigned to something like error.
Contrary to the other answer, shifting to the right has the effect to divide by a power of two, in this case >> 10 would divide by 1024. But a real division would be better, more clear, and optimized by the compiler with a shift anyway. So I find this shift ugly.
The intent is to implement some float math without actually use floating point numbers - it is a kind of fixed point calculation, where the fractional part is about 10 bits. To understand, assuming to simplify the derivative coefficient=0, an m_proportionalGain set to 1024 would mean 1, while if set to 512 it would mean 0.5. In fact in the case of proportional=1024, and error=100, the formula would give
100*1024 / 1024 = 100
(gain=1), while proportional=512 would give
100*512 / 1024 = 50
(gain=0.5).
As for previous error m_prevError set to 0x80000000, it is simply a special value which is checked in the loop to see if "there is already" a previous error. If not, i.e. if prevError has the special value, the entire loop is skipped once; in other words, it serves the purpose to skip the first update after creation of the object. Not very cleaver I suppose, I would prefer to simply set the previous error equal to 0 and skip completely the check in ::update(). Using special values as flag has the problem that sometimes the calculations result in the special value itself - it would be a big bug. If absolutely needed, it is better to use a true flag.
All in all, I think this is a poor PID algorithm, as it lacks completely the integrative part; it seems that the variable m_pos is thought for this integrative purpose, it is managed quite that way, but never used - only set. Nevertheless this algorithm can work, but all depends on the target system and the wanted performances: on most situations, this algorithm leaves a residual error.

Find leading 1s in the binary number

everyone,
I am new in C and I try to understand the work with bytes, binary numbers and another important thing for the beginner.
I hope someone can push me in the right direction here.
For example, I have a 32- bits number 11000000 10101000 00000101 0000000 (3232236800).
I also assigned each part of this number to separate variables as a=11000000 (192), b = 10101000 (168), c =00000101 (5) d = 0000000 (0). I am not sure if I really need this.
Is there any way to find the last 1 in the number and use this location to calculate the number of leading 1s?
Thank you for help!
You can determine the bitposition of the first leading 1 by this formula:
floor(ln(number)/ln(2))
Where "floor()" means rounding down.
For counting the number of consecutive leading ones (if I get the second part of your question correctly) I can only imagine a loop.
Note 1:
The formula is the math formula for "logarithm of number on the base of 2".
The same works with log10(). Basically you can use any logarithm (i.e. to any base) this way to adapt to a different base.
Note 2:
It is of course questionable whether this formula is more efficient than search from MSB downwards with a loop. It could be with good FPU support. It probably is not for 8bit values. Double check in case you are out to speed optimise.
Sorry I am not a C expert, but here's the Python code I came up with:
num_ones = 0
while integer > 0:
if integer % 2 == 1:
num_ones += 1
else:
num_ones = 0
integer = integer >> 1
Basically, I count the number of continuous 1's by bit shifting the given integer.
A zero would reset the counter.

precision multiplication of 255-bit integer in radix-2^16 [duplicate]

I'm trying to learn C and have come across the inability to work with REALLY big numbers (i.e., 100 digits, 1000 digits, etc.). I am aware that there exist libraries to do this, but I want to attempt to implement it myself.
I just want to know if anyone has or can provide a very detailed, dumbed down explanation of arbitrary-precision arithmetic.
It's all a matter of adequate storage and algorithms to treat numbers as smaller parts. Let's assume you have a compiler in which an int can only be 0 through 99 and you want to handle numbers up to 999999 (we'll only worry about positive numbers here to keep it simple).
You do that by giving each number three ints and using the same rules you (should have) learned back in primary school for addition, subtraction and the other basic operations.
In an arbitrary precision library, there's no fixed limit on the number of base types used to represent our numbers, just whatever memory can hold.
Addition for example: 123456 + 78:
12 34 56
78
-- -- --
12 35 34
Working from the least significant end:
initial carry = 0.
56 + 78 + 0 carry = 134 = 34 with 1 carry
34 + 00 + 1 carry = 35 = 35 with 0 carry
12 + 00 + 0 carry = 12 = 12 with 0 carry
This is, in fact, how addition generally works at the bit level inside your CPU.
Subtraction is similar (using subtraction of the base type and borrow instead of carry), multiplication can be done with repeated additions (very slow) or cross-products (faster) and division is trickier but can be done by shifting and subtraction of the numbers involved (the long division you would have learned as a kid).
I've actually written libraries to do this sort of stuff using the maximum powers of ten that can be fit into an integer when squared (to prevent overflow when multiplying two ints together, such as a 16-bit int being limited to 0 through 99 to generate 9,801 (<32,768) when squared, or 32-bit int using 0 through 9,999 to generate 99,980,001 (<2,147,483,648)) which greatly eased the algorithms.
Some tricks to watch out for.
1/ When adding or multiplying numbers, pre-allocate the maximum space needed then reduce later if you find it's too much. For example, adding two 100-"digit" (where digit is an int) numbers will never give you more than 101 digits. Multiply a 12-digit number by a 3 digit number will never generate more than 15 digits (add the digit counts).
2/ For added speed, normalise (reduce the storage required for) the numbers only if absolutely necessary - my library had this as a separate call so the user can decide between speed and storage concerns.
3/ Addition of a positive and negative number is subtraction, and subtracting a negative number is the same as adding the equivalent positive. You can save quite a bit of code by having the add and subtract methods call each other after adjusting signs.
4/ Avoid subtracting big numbers from small ones since you invariably end up with numbers like:
10
11-
-- -- -- --
99 99 99 99 (and you still have a borrow).
Instead, subtract 10 from 11, then negate it:
11
10-
--
1 (then negate to get -1).
Here are the comments (turned into text) from one of the libraries I had to do this for. The code itself is, unfortunately, copyrighted, but you may be able to pick out enough information to handle the four basic operations. Assume in the following that -a and -b represent negative numbers and a and b are zero or positive numbers.
For addition, if signs are different, use subtraction of the negation:
-a + b becomes b - a
a + -b becomes a - b
For subtraction, if signs are different, use addition of the negation:
a - -b becomes a + b
-a - b becomes -(a + b)
Also special handling to ensure we're subtracting small numbers from large:
small - big becomes -(big - small)
Multiplication uses entry-level math as follows:
475(a) x 32(b) = 475 x (30 + 2)
= 475 x 30 + 475 x 2
= 4750 x 3 + 475 x 2
= 4750 + 4750 + 4750 + 475 + 475
The way in which this is achieved involves extracting each of the digits of 32 one at a time (backwards) then using add to calculate a value to be added to the result (initially zero).
ShiftLeft and ShiftRight operations are used to quickly multiply or divide a LongInt by the wrap value (10 for "real" math). In the example above, we add 475 to zero 2 times (the last digit of 32) to get 950 (result = 0 + 950 = 950).
Then we left shift 475 to get 4750 and right shift 32 to get 3. Add 4750 to zero 3 times to get 14250 then add to result of 950 to get 15200.
Left shift 4750 to get 47500, right shift 3 to get 0. Since the right shifted 32 is now zero, we're finished and, in fact 475 x 32 does equal 15200.
Division is also tricky but based on early arithmetic (the "gazinta" method for "goes into"). Consider the following long division for 12345 / 27:
457
+-------
27 | 12345 27 is larger than 1 or 12 so we first use 123.
108 27 goes into 123 4 times, 4 x 27 = 108, 123 - 108 = 15.
---
154 Bring down 4.
135 27 goes into 154 5 times, 5 x 27 = 135, 154 - 135 = 19.
---
195 Bring down 5.
189 27 goes into 195 7 times, 7 x 27 = 189, 195 - 189 = 6.
---
6 Nothing more to bring down, so stop.
Therefore 12345 / 27 is 457 with remainder 6. Verify:
457 x 27 + 6
= 12339 + 6
= 12345
This is implemented by using a draw-down variable (initially zero) to bring down the segments of 12345 one at a time until it's greater or equal to 27.
Then we simply subtract 27 from that until we get below 27 - the number of subtractions is the segment added to the top line.
When there are no more segments to bring down, we have our result.
Keep in mind these are pretty basic algorithms. There are far better ways to do complex arithmetic if your numbers are going to be particularly large. You can look into something like GNU Multiple Precision Arithmetic Library - it's substantially better and faster than my own libraries.
It does have the rather unfortunate misfeature in that it will simply exit if it runs out of memory (a rather fatal flaw for a general purpose library in my opinion) but, if you can look past that, it's pretty good at what it does.
If you cannot use it for licensing reasons (or because you don't want your application just exiting for no apparent reason), you could at least get the algorithms from there for integrating into your own code.
I've also found that the bods over at MPIR (a fork of GMP) are more amenable to discussions on potential changes - they seem a more developer-friendly bunch.
While re-inventing the wheel is extremely good for your personal edification and learning, its also an extremely large task. I don't want to dissuade you as its an important exercise and one that I've done myself, but you should be aware that there are subtle and complex issues at work that larger packages address.
For example, multiplication. Naively, you might think of the 'schoolboy' method, i.e. write one number above the other, then do long multiplication as you learned in school. example:
123
x 34
-----
492
+ 3690
---------
4182
but this method is extremely slow (O(n^2), n being the number of digits). Instead, modern bignum packages use either a discrete Fourier transform or a Numeric transform to turn this into an essentially O(n ln(n)) operation.
And this is just for integers. When you get into more complicated functions on some type of real representation of number (log, sqrt, exp, etc.) things get even more complicated.
If you'd like some theoretical background, I highly recommend reading the first chapter of Yap's book, "Fundamental Problems of Algorithmic Algebra". As already mentioned, the gmp bignum library is an excellent library. For real numbers, I've used MPFR and liked it.
Don't reinvent the wheel: it might turn out to be square!
Use a third party library, such as GNU MP, that is tried and tested.
You do it in basically the same way you do with pencil and paper...
The number is to be represented in a buffer (array) able to take on an arbitrary size (which means using malloc and realloc) as needed
you implement basic arithmetic as much as possible using language supported structures, and deal with carries and moving the radix-point manually
you scour numeric analysis texts to find efficient arguments for dealing by more complex function
you only implement as much as you need.
Typically you will use as you basic unit of computation
bytes containing with 0-99 or 0-255
16 bit words contaning wither 0-9999 or 0--65536
32 bit words containing...
...
as dictated by your architecture.
The choice of binary or decimal base depends on you desires for maximum space efficiency, human readability, and the presence of absence of Binary Coded Decimal (BCD) math support on your chip.
You can do it with high school level of mathematics. Though more advanced algorithms are used in reality. So for example to add two 1024-byte numbers :
unsigned char first[1024], second[1024], result[1025];
unsigned char carry = 0;
unsigned int sum = 0;
for(size_t i = 0; i < 1024; i++)
{
sum = first[i] + second[i] + carry;
carry = sum - 255;
}
result will have to be bigger by one place in case of addition to take care of maximum values. Look at this :
9
+
9
----
18
TTMath is a great library if you want to learn. It is built using C++. The above example was silly one, but this is how addition and subtraction is done in general!
A good reference about the subject is Computational complexity of mathematical operations. It tells you how much space is required for each operation you want to implement. For example, If you have two N-digit numbers, then you need 2N digits to store the result of multiplication.
As Mitch said, it is by far not an easy task to implement! I recommend you take a look at TTMath if you know C++.
One of the ultimate references (IMHO) is Knuth's TAOCP Volume II. It explains lots of algorithms for representing numbers and arithmetic operations on these representations.
#Book{Knuth:taocp:2,
author = {Knuth, Donald E.},
title = {The Art of Computer Programming},
volume = {2: Seminumerical Algorithms, second edition},
year = {1981},
publisher = {\Range{Addison}{Wesley}},
isbn = {0-201-03822-6},
}
Assuming that you wish to write a big integer code yourself, this can be surprisingly simple to do, spoken as someone who did it recently (though in MATLAB.) Here are a few of the tricks I used:
I stored each individual decimal digit as a double number. This makes many operations simple, especially output. While it does take up more storage than you might wish, memory is cheap here, and it makes multiplication very efficient if you can convolve a pair of vectors efficiently. Alternatively, you can store several decimal digits in a double, but beware then that convolution to do the multiplication can cause numerical problems on very large numbers.
Store a sign bit separately.
Addition of two numbers is mainly a matter of adding the digits, then check for a carry at each step.
Multiplication of a pair of numbers is best done as convolution followed by a carry step, at least if you have a fast convolution code on tap.
Even when you store the numbers as a string of individual decimal digits, division (also mod/rem ops) can be done to gain roughly 13 decimal digits at a time in the result. This is much more efficient than a divide that works on only 1 decimal digit at a time.
To compute an integer power of an integer, compute the binary representation of the exponent. Then use repeated squaring operations to compute the powers as needed.
Many operations (factoring, primality tests, etc.) will benefit from a powermod operation. That is, when you compute mod(a^p,N), reduce the result mod N at each step of the exponentiation where p has been expressed in a binary form. Do not compute a^p first, and then try to reduce it mod N.
Here's a simple ( naive ) example I did in PHP.
I implemented "Add" and "Multiply" and used that for an exponent example.
http://adevsoft.com/simple-php-arbitrary-precision-integer-big-num-example/
Code snip
// Add two big integers
function ba($a, $b)
{
if( $a === "0" ) return $b;
else if( $b === "0") return $a;
$aa = str_split(strrev(strlen($a)>1?ltrim($a,"0"):$a), 9);
$bb = str_split(strrev(strlen($b)>1?ltrim($b,"0"):$b), 9);
$rr = Array();
$maxC = max(Array(count($aa), count($bb)));
$aa = array_pad(array_map("strrev", $aa),$maxC+1,"0");
$bb = array_pad(array_map("strrev", $bb),$maxC+1,"0");
for( $i=0; $i<=$maxC; $i++ )
{
$t = str_pad((string) ($aa[$i] + $bb[$i]), 9, "0", STR_PAD_LEFT);
if( strlen($t) > 9 )
{
$aa[$i+1] = ba($aa[$i+1], substr($t,0,1));
$t = substr($t, 1);
}
array_unshift($rr, $t);
}
return implode($rr);
}

How do you use bitwise operators, masks, to find if a number is a multiple of another number?

So I have been told that this can be done and that bitwise operations and masks can be very useful but I must be missing something in how they work.
I am trying to calculate whether a number, say x, is a multiple of y. If x is a multiple of y great end of story, otherwise I want to increase x to reach the closest multiple of y that is greater than x (so that all of x fits in the result). I have just started learning C and am having difficulty understanding some of these tasks.
Here is what I have tried but when I input numbers such as 5, 9, or 24 I get the following respectively: 0, 4, 4.
if(x&(y-1)){ //if not 0 then multiple of y
x = x&~(y-1) + y;
}
Any explanations, examples of the math that is occurring behind the scenes, are greatly appreciated.
EDIT: So to clarify, I somewhat understand the shifting of bits to get whether an item is a multiple. (As was explained in a reply 10100 is a multiple of 101 as it is just shifted over). If I have the number 16, which is 10000, its complement is 01111. How would I use this complement to see if an item is a multiple of 16? Also can someone give a numerical explanation of the code given above? Showing this may help me understand why it does not work. Once I understand why it does not work I will be able to problem solve on my own I believe.
Why would you even think about using bit-wise operations for this? They certainly have their place but this isn't it.
A better method is to simply use something like:
unsigned multGreaterOrEqual(unsigned x, unsigned y) {
if ((x % y) == 0)
return x;
return (x / y + 1) * y;
}
In the trivial cases, every number that is an even multiple of a power of 2 is just shifted to the left (this doesn't apply when possibly altering the sign bit)
For example
10100
is 4 times
101
and
10100
is 2 time
1010
As for other multiples, they would have to be found by combining the outputs of two shifts. You might want to look up some primitive means of computer division, where division looks roughly like
x = a / b
implemented like
buffer = a
while a is bigger than b; do
yes: subtract a from b
add 1 to x
done
faster routines try to figure out higher level place values first, skipping lots of subtractions. All of these routine can be done bitwise; but it is a big pain. In the ALU these routines are done bitwise. Might want to look up a digital logic design book for more ideas.
Ok, so I have discovered what the error was in my code and since the majority say that it is impossible to calculate whether a number is a multiple of another number using masks I figured I would share what I have learned.
It is possible! - if you are using the correct data types that is.
The code given above works if y is declared as a constant unsigned long as x which was being passed in was also an unsigned long. The key point is not the long or constant part but that the number is unsigned. This sign bit causes miscalculation as the first place in the number indicates sign and when performing bitwise operations signs can get muddled.
So here is my code if we are looking for multiples of 16:
const unsigned long y = 16; //declared globally in my case
Then an unsigned long is passed to the function which runs the following code:
if(x&(y-1)){ //if not 0 then multiple of y
x = x&~(y-1) + y;
}
x will now be the size of the nearest multiple of 16.

Bit count for all numbers up to 1048576 is wrong [duplicate]

This question already has answers here:
Binary numbers with the same quantity of 0s and 1s
(6 answers)
Closed 8 years ago.
I want to convert all integers below 1048576 to binary and display all numbers which have the same number of bits set as unset. My program works fine when I use a table t of 20 integers, in which case cpt records the correct result.
However, when I use a table t of 40 integers (which means I want the numbers with 20 '1' bits and 20 '0' bits) the counter is set to 1. What is wrong?
int main(){
long int a;
int r,j,i;
long int aux;
int z,u;
long int cpt;
int t[40];
for(int k=0;k<40;k++) t[k]=0;
cpt=0;
for(a=0;a<1048576;a++){
j=0;u=0;z=0;
aux=a;
do{
r=aux%2;
switch(r){
case 0 : t[j]=0;
aux=(aux/2);
j++;
break;
case 1 : t[j]=1;
aux=((aux-1)/2);
j++;
break;
}
}while(aux!=0);
for(i=0;i<40;i++){
if(t[i]==0) z++;
else u++;
}
if(z==u) cpt++;
}
printf("%d",cpt);
getchar();
}
Your loop only goes to 1048576, which is 2^20.
Don't you need to loop until 2^40?
Also, note that int may not be 40 bits wide.
Note:
The naive solution to check all numbers doesn't scale well. Perhaps you should consider a smarter solution?
Because only one number in the range [0, 1048576) has exactly as many bits 1 as 0, when counted in your 40 "bit" array.
The flaw in your logic is that you do not examine all numbers in a given range. For instance, when you want to examine all 40-bit integers, you need to iterate until 2^40 and not 2^20.
Lastly, this brute force solution won't work very well for your problem. Instead, try to consider the pattern that appears when you examine the number of paths from the top-left node and proceeding to the down or right for a small array on a piece of paper. Does one emerge? If you're math-inclined, you will instantly recognise it; otherwise, take a minute to look through the binomial coefficients.
As others have said, the main thing that is wrong is the algorithm you are using (exhaustive search); you would need to loop from 0 to 240-1 to iterate across the entire set of numbers to be tested (rather than to 220-1), which would be an impractical number of iterations, not least as there are faster ways.
Consider the maths of the problem: you want a 40 bit field, with 20 bits set to 1. So, you are choosing 20 things from 40. Think about the nCr (combination operator from permutations and combinations); that will give you the link to the binomial coefficients. Now think how you might write an algorithm to go through every combination.
Your code would also be more comprehensible if it did not have single letter variable names, and had some comments explaining what it was meant to be doing.
If you are having difficulty remembering the bit width of integer types, I suggest you use
#include <stdint.h>
and use types like int64_t which is guaranteed to be 64 bits. See:
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdint.h.html
(Note that OP apparently wanted a list of the numbers with 20 bits set, rather just the count of such numbers, so merely looking at binomial coefficients is insufficient).
try using a long long int:
unsigned long long int a;
to fasten and clear a lot of code try also using popcount, it's a function that returns the number of 1-bits in x: http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html.
//I'm not 100% sure if the popcount will work with long long ints, but you can try.
BTW I have a question about the same euler problem #: Binary numbers with the same quantity of 0s and 1s

Resources