I have to calculate the remainder of two big numbers in C. One has the size of 938 or 256 Bit and the other has a size of 85 Bit. Both are no 2^n values!
My basic idea is to put every bit as one element of a short-array and calculate the remainder with basic bit operations. But I have no good idea how to do this. So I hope somebody here can help me.
For those who are interested I'm programming an ETCS - Encoder according to UNISIG-SUBSET 036 http://www.era.europa.eu/Document-Register/Documents/Set-2-Index009-SUBSET-036%20v300.pdf on page 36 - 39 and im trying to calculate the check bits.
Assuming you are working in decimal base, and you want to calculate X mod Y, you can do something like this:
1. mod = 0;
2. mod = ((mod * 10) + mostCignificantDigit)%Y;
3. remove the mostCignificantDigit from your number, and return to 2.
In other words, say you have the number in digit array A:
mod = 0;
for (int index = 0; index < A.size(); ++index)
mod = ((mod*10)+A[index]) %Y
Related
Given a number, I want to modify the Nth digit of the number.
For example, given 1237645, I want to change the 4th digit from the right, which is 7 in this case, to say 5.
The only way in which I can think of is to do this
N = 1237645
fourthDigit = (N / 1000) % 10
N -= fourthDigit * 1000 // make fourth digit 0
N += 5 * 1000 // make fourth digit 5
But this is quite inefficient. Is there a better way to this? I cannot use array to represent N due to memory constraints.
You can do it in one arithmetic operation:
N = 1237645
fourthDigit = (N / 1000) % 10
N -= (fourthDigit-5) * 1000
provided fourthDigit >= 5, otherwise the last line becomes
N += (newDigit-fourthDigit)*1000
Is this embedded system programming?
If it is, then try storing numbers as binary-coded decimal (BCD), then convert to binary if you need to. It is probably easier to convert from BCD to binary than the other way around.
Also see: http://homepage.divms.uiowa.edu/~jones/bcd/bcd.html
BTW, right here in the room with me is a clock which keeps time in BCD. This way, it doesn't have to divide by 10 for display.
I am stuck in a program while finding modulus of division.
Say for example I have:
((a*b*c)/(d*e)) % n
Now, I cannot simply calculate the expression and then modulo it to n as the multiplication and division are going in a loop and the value is large enough to not fit even in long long.
As clarified in comments, n can be considered prime.
I found that, for multiplication, I can easily calculate it as:
((a%n*b%n)%n*c%n)%n
but couldn't understand how to calculate the division part then.
The problem I am facing is say for a simple example:
((7*3*5)/(5*3)) % 11
The value of above expression would be 7
but if I calculate the multiplication, modulo, it would be like:
((7%11)*(3%11))%11 = 10
((10%11)*(5%11))%11 = 6
now I am left with 6/15 and I have no way to generate correct answer.
Could someone help me. Please make me understand the logic by above example.
Since 11 is prime, Z11 is a field. Since 15 % 11 is 4, 1/15 equals 3 (since 3 * 4 % 11 is 1). Therefore, 6/15 is 6 * 3 which is 7 mod 11.
In your comments below the question, you clarify that the modulus will always be a prime.
To efficiently generate a table of multiplicative inverses, you can raise 2 to successive powers to see which values it generates. Note that in a field Zp, where p is an odd prime, 2p-1 = 1. So, for Z11:
2^1 = 2
2^2 = 4
2^3 = 8
2^4 = 5
2^5 = 10
2^6 = 9
2^7 = 7
2^8 = 3
2^9 = 6
So the multiplicative inverse of 5 (which is 24) is 26 (which is 9).
So, you can generate the above table like this:
power_of_2[0] = 1;
for (int i = 1; i < n; ++i) {
power_of_2[i] = (2*power_of_2[i-1]) % n;
}
And the multiplicative inverse table can be computed like this:
mult_inverse[1] = 1;
for (int i = 1; i < n; ++i) {
mult_inverse[power_of_2[i]] = power_of_2[n-1-i];
}
In your example, since 15 = 4 mod 11, you actually end up with having to evaluate (6/4) mod 11.
In order to find an exact solution to this, rearrange it as 6 = ( (x * 4) mod 11), which makes clearer how the modulo division works.
If nothing else, if the modulus is always small, you can iterate from 0 to modulus-1 to get the solution.
Note that when the modulus is not prime, there may be multiple solutions to the reduced problem. For instance, there are two solutions to 4 = ( ( x * 2) mod 8): 2 and 6. This will happen for a reduced problem of form:
a = ( (x * b) mod c)
whenever b and c are NOT relatively prime (ie whenever they DO share a common divisor).
Similarly, when b and c are NOT relatively prime, there may be no solution to the reduced problem. For instance, 3 = ( (x * 2) mod 8) has no solution. This happens whenever the largest common divisor of b and c does not also divide a.
These latter two circumstances are consequences of the integers from 0 to n-1 not forming a group under multiplication (or equivalently, a field under + and *) when n is not prime, but rather forming simply the less useful structure of a ring.
I think the way the question is asked, it should be assumed that the numerator is divisible by the denominator. In that case the finite field solution for prime n and speculations about possible extensions and caveats for non-prime n is basically overkill. If you have all the numerator terms and denominator terms stored in arrays, you can iteratively test pairs of (numerator term, denominator term) and quickly find the greatest common divisor (gcd), and then divide the numerator term and denominator term by the gcd. (Finding the gcd is a classical problem and you can easily find a simple solution online.) In the worst case you will have to iterate over all possible pairs but at some point, if the denominator indeed divides the numerator, then you'll eventually be left with reduced numerator terms and all denominator terms will be 1. Then you're ready to apply multiplication (avoiding overflow) the way you described.
As n is prime, dividing an integer b is simply multiplying b's inverse. That is:
(a / b) mod n = (a * inv(b)) mod n
where
inv(b) = (b ^ (n - 2)) mod n
Calculating inv(b) can be done in O(log(n)) time using the Exponentiation by squaring algorithm. Here is the code:
int inv(int b, int n)
{
int r = 1, m = n - 2;
while (m)
{
if (m & 1) r = (long long)r * b % n;
b = (long long)b * b % n;
m >>= 1;
}
return r;
}
Why it works? According to Fermat's little theorem, if n is prime, b ^ (n - 1) mod n = 1 for any positive integer b. Therefore we have inv(b) * b mod n = 1.
Another solution for finding inv(b) is the Extended Euclidean algorithm, which needs a bit more code to implement.
I think you can distribute the division like
z = d*e/3
(a/z)*(b/z)*(c/z) % n
Remains only the integer division problem.
I think the problem you had was that you picked a problem that was too simple for an example. In that case the answer was 7 , but what if a*b*c was not evenly divisible by c*d ? You should probably look up how to do division with modulo first, it should be clear to you :)
Instead of dividing, think in terms of multiplicative inverses. For each number in a mod-n system, there ought to be an inverse, if certain conditions are met. For d and e, find those inverses, and then it's all just multiplying. Finding the inverses is not done by dividing! There's plenty of info out there...
Let's say I have a number like 21 and I want to split it up so that I get the numbers 2 and 1.
To get 1, I could do 1 mod 10. So basically, the last digit can be found out by using mod 10.
To get 2, I could do (21 - (1 mod 10))/10.
The above techniques will work with any 2-digit number.
However, let me add a further constraint, that mod can only be used with powers of 2. Then the above method can't be used.
What can be done then?
2 == 23 / 10
3 == 23 - (23 / 10) * 10
To get 2 you can just do
int x = 23 / 10;
remember that integer division drops the fractional portion (as it can't be represented in an integer).
Modulus division (and regular division) can be used for any power, not just powers of two. Also a power of two is not the same thing as a two digit number.
To split up a three digit number
int first = 234/100;
int second = (234/10)-first*10;
int third = (234/1)-first*100-second*10;
with a little work, it could also look like
int processed = 0;
int first = 234/100-processed;
processed = processed + first;
processed = processed * 10;
int second = 234/10-processed;
processed = processed + second;
processed = processed * 10;
... and so on ...
If you put a little more into it, you can write it up as a loop quite easily.
what about
x%10 for the second digit and
x/10 for the first?
I have an Array of 8 elements: Bin[8].
Bin represents a range container: I receive a number N, such as 0 <= N <= 255.
If N < 32 ==> Bin[0] += 1
Else If 32 <= N < 64 ==> Bin[1] += 1
... etc.
I want a fast solution that does not require an If-Else directive, as I have multiple Bins to handle.
I am using Java, but a solution in any programming language is accepted.
Thank you.
Ensure your number N is indeed 0 <= N <= 255, then simply:
Bin[N/32]++;
Edit: Another poster mentioned shifting right by 5 bits. This will work too, however I feel dividing by 32 shows intent cleaner and any modern compiler will optimize the division away into a bitshift if it's more efficient on the platform you're targeting anyway.
We can use some bitwise operators for this:
binIndex = N >> 5;
Then
Bin[binIndex]++;
This just ignores the low 5 bits of the number, using the top three bits (if N <= 255) as an index into the array of bins.
Just use integer division (truncation):
Bin[N / 32] += 1;
I'm writing code for a microprocessor with fast integer arithmetic and not so fast float arithmetic. I need to divide an integer by a number from 1 to 9 and convert result back to integer.
I made a float array with members like 0, 1, 0.5, 0.3333 etc.
But i think there is MAGIC constants (like 0x55555556) for a numbers except (1/3).
What are this numbers?
If the division instruction on your microcontroller is fast enough, use that. If you need the fractional part of the result, you may be able to use the remainder; on most architectures, the division instruction puts the quotient in one register and the remainder in another.
If your division instruction is not fast enough but the multiplication instruction is, you can use the following technique (and it sounds as if this is the technique you're after). On most architectures, multiplying a 32-bit number by another 32-bit number results in a 64-bit result; the more significant half is stored in one register and the less significant half is stored in the other. You can exploit this by realizing that division by a number n is the same as multiplying by (2^32)/n, then taking the more significant 32 bits of the result. In other words, if you want to divide by 3, you can instead multiply by 0x100000000/3 = 0x55555555, then take the more significant 32 bits of the result.
What you're doing here is really a form of fixed-point arithmetic. Take a look at the Wikipedia article for more information.
I'm assuming, based on the micro-controller tag, you don't have a fast integer divide. My answer is also for unsigned values - it will work for signed values, you just have to limit the numbers used in the tricky bit below.
A good start is divide by 2, 4 and 8. These can be done with right shifts of 1, 2 and 3 bits respectively, assuming your CPU has a logical right-shift instruction.
Secondly, dividing by 1 is just keeping the number as-is. That just leaves, 3, 5, 6, 7 and 9.
Tricky bit starts here:
For the other numbers, you can use the fact that a divide can be replaced by a multiply-and-shift.
Let's say you have a 16-bit processor. To divide by N, you multiply by 256/N and shift right 8 bits:
N = 3, multiply by 85
N = 5, multiply by 51
N = 6, multiply by 43
N = 7, multiply by 37
N = 9, multiply by 28
Take the random example of 72 / 5. Multiply 72 by 51 to get 3672 then shift right 8 bits to get 14.
In order for this to work, your numbers that you're using must not overflow the 16 bits. Since your worst case is multiply-by-85, you can handle numbers up to 771.
The reason this works is because a shift-right of 8 bits is the same as dividing by 256, and:
m * (256 / n) / 256
= m / (n / 256) / 256
= m / n * 256 / 256
= m / n * (256 / 256)
= m / n
If you have a 32-bit processor, the values and ranges change somewhat, since it's 65536/N:
N = 3, multiply by 21,846, right shift 16 bits, max value roughly 196,600.
N = 5, multiply by 13,108.
N = 6, multiply by 10,923.
N = 7, multiply by 9,363.
N = 9, multiply by 7,282.
Again, let's choose the random 20,000 / 7: 20,000 multiplied by 9,363 is 187,260,000 and, when you right shift that 16 bits, you get 2,857 - the real result is 2,857.
The following test program in C shows the accuracy figures for the values given. It uses signed values so is only good up to about 98,000 but you can see that the largest error is 1 and that it occurs at the low point of 13,110 (only 0.008% error).
#include <stdio.h>
int res[5] = {0};
int low[5] = {-1,-1,-1,-1,-1};
int da[] = {3,5,6,7,9};
int ma[] = {21846,13108,10923,9363,7282};
int main (void) {
int n, i;
for (n = 0; n < 98000; n++) {
for (i = 0; i < sizeof(da)/sizeof(da[0]); i++) {
int r1 = n / da[i];
int r2 = (n * ma[i])>>16;
int dif = abs (r1-r2);
if (dif >= 5) {
printf ("%d / %d gives %d and %d\n", n, da[i], r1, r2);
return 1;
}
res[dif]++;
if (low[dif] == -1) {
low[dif] = n;
}
}
}
for (i = 0; i < sizeof(res)/sizeof(res[0]); i++) {
printf ("Difference of %d: %6d, lowest value was %6d\n", i, res[i], low[i]);
}
return 0;
}
This outputs:
Difference of 0: 335874, lowest value was 0
Difference of 1: 154126, lowest value was 13110
Difference of 2: 0, lowest value was -1
Difference of 3: 0, lowest value was -1
Difference of 4: 0, lowest value was -1