Finding the remainder of a large multiplication in C++ - c++

I would like to ask some help concerning the following problem. I need to create a function that will multiply two integers and extract the remainder of this multiplication divided by a certain number (in short, (x*y)%A).
I am using unsigned long long int for this problem, but A = 15! in this case, and both x and y have been calculated modulo A previously. Thus, x*y can be greater than 2^64 - 1, therefore overflowing.
I did not want to use external libraries. Could anyone help me designing a short algorithm to solve this problem?
Thanks in advance.

If you already have mod A of x and y, why not use them? something like,
if,
x = int_x*A + mod_x
y = int_y*A + mod_y
then
(x*y)%A = ((int_x*A + mod_x)(int_y*A + mod_y))%A = (mod_x*mod_y)%A
mod_x*mod_y should be much smaller, right?
EDIT:
If you are trying to find the modulus wrt a large number like 10e11, I guess you would have to use another method. But while not really efficient, something like this would work
const int MAX_INT = 10e22 // get max int
int larger = max(mod_x, mod_y) // get the larger number
int smaller = max(mod_x, mod_y)
int largest_part = floor(MAX_INT/smaller)
if (largest_part > larger):
// no prob of overflow. use normal routine
else:
int larger_array = []
while(largest_part < larger):
larger_array.append(largest_part)
larger -= largest_part
largest_part = floor(MAX_INT/smaller)
// now use the parts array to calculate the mod by going through each elements mod and adding them etc
If you understand this code and the setup, you should be able to figure out the rest

Related

Why does this recursive algorithm give the wrong answer on input 2,147,483,647?

I'm working on the following question:
Given a positive integer n and you can do operations as follow:
If n is even, replace n with n/2.
If n is odd, you can replace n with either n + 1 or n - 1.
What is the minimum number of replacements needed for n to become 1?
Here's the code I've come up with:
class Solution {
private:
unordered_map<int, long long> count_num;
public:
int integerReplacement(int n) {
count_num[1] = 0;count_num[2] = 1;count_num[3] = 2;
if(!count_num.count(n)){
if(n%2){
count_num[n] = min( integerReplacement((n-1)/2), integerReplacement((n+1)/2) )+2;
}else{
count_num[n] = integerReplacement(n/2) +1;
}
}
return(count_num[n]);
}
};
When the input is 2147483647, my code incorrectly outputs 33 instead of the correct answer, 32. Why is my code giving the wrong answer here?
I suspect that this is integer overflow. The number you've listed (2,147,483,647) is the maximum possible value that can fit into an int, assuming you're using a signed 32-bit integer, so if you add one to it, you overflow to INT_MIN, which is −2,147,483,648. From there, it's not surprising that you'd get the wrong answer, since this value isn't what you expected to get.
The overflow specifically occurs when you compute
integerReplacement((n+1)/2)
and so you'll need to fix that case to compute (n+1) / 2 without overflowing. This is a pretty extreme edge case, so I'm not surprised that the code tripped up on it.
One way to do this is to note that if n is odd, then (n + 1) / 2 is equal to (n / 2) + 1 (with integer division). So perhaps you could rewrite this as
integerReplacement((n / 2) + 1)
which computes the same value but doesn't have the overflow.

Program taking too long for large input

I am using an equation in which we have to find the maximum value that x can take given the value of b. Both x and b can take only nonnegative integer values. The equation is:
x^4+x^3+x^2+x+1≤b
I have written the following code(apparently dumb) to solve it:
#include<iostream>
#include<climits>
using namespace std;
int main()
{
unsigned long long b,x=0;
cout<<"hey bro, value of b:";
cin>>b;
while(x++<b)
if(x*x*x*x+x*x*x+x*x+x+1>b)
break;
if(b==0)
cout<<"Sorry,no value of x satisfies the inequality"<<endl;
else
cout<<"max value of x:"<<x-1<<endl;
return 0;
}
The above code works fine upto b=LONG_MAX but after for b=LONG_LONG_MAX or b=ULLONG_MAX, it starts taking forever. How can I solve this problem so that it works fine for at most b=ULLONG_MAX?
If for x = m, the inequality holds, then it also holds for all integers < m. If it doesn't hold for m, then it doesn't hold for any integer > m. What algorithm does this suggest?
If you want to spoil yourself, click here for the algorithm.
This is not just an optimization issue. (For optimization, see IVlad's answer). It is also a correctness issue. With very large values, the expression causes integer overflow: to put it simply, it wraps around from ULLONG_MAX back to zero, and your loop carries on having not detected this. You need to build overflow detection in your code.
A really simple observation solves your problem in O(1) time.
Find k = sqrt(sqrt(b))
If k satisfies your inequality, k is your answer. If it does not, k-1 is your answer.
Old answer (real problem here is not big number of iterations, but integer overflow; please read from 'Update' part; I keep this part here for history of false assumptions):
These values are very big. When your program checks each value from 0 to LONG_LONG_MAX, it shold make about 9*10^12 operations, isn't it? For ULLONG_MAX we have about 18*10^12 operations. Try to modify this program to see actual speed of processing:
while (x++ < b)
{
if (x % 1000000 == 0)
cout << " current x: " << x << endl;
if (x*x*x*x+x*x*x+x*x+x+1>b)
break;
}
So, you need to optimize this algorithm (i.e. reduce number of iterations): since your function is monotonic, you can use Binary search algorithm (see Bisection method too for clarification).
Also there is a possible problem with integer overflow: function x*x*x*x for big values x will be calculated wrong. Just imagine thay your type is unsigned char (1 byte). For example, when your program calculates 250*250*250*250 you expect 3906250000, but in fact you have 3906250000 % 256 (i.e. 16). So, if x is too big, it is possible, that your function will return value < b (and it will be strange; theoretically it can brake your optimized algorithm). Good news is that you will not see this problem, if do every check correctly. But for more complex functions you would also need to support long math (for example, use GMP or another implementation).
Update: How to avoid overflow risks?
We need to find maximal allowed value of x (let's call it xmax). Value x is allowed if x*x*x*x+x*x*x+x*x+x+1 < ULLONG_MAX. So, answer on initial question (about x*x*x*x+x*x*x+x*x+x+1 < b) is not bigger than xmax. Let's find xmax (just solve equation x*x*x*x+x*x*x+x*x+x+1=ULLONG_MAX in any system, for example WolframAlpha: anwer is about 65535.75..., so xmax==65535. So, if we check x from 0 to xmax we will not have overflow problems. Also it is our initial values for binary search algorithm.
Also it means, that we do not need to use binary search algorithm here, because it is enought to check only 65535 values. If x==65535 is not answer, we have to stop and return answer 65536.
If we need cross-platform solution without hardcoding of xmax, we can use any bigint implementation (GMP or any simpler solution) or implement more accurate multiplication and other operations. Example: if we need to multyply x and y, we can calculate z=ULLONG_MAX/x and compare this value and y. If z<y, we can't multiply x and y without overflow.
You could try finding an upper limit and working down from there.
// Find the position of the most significant bit.
int topBitPosition = 0;
while(b >> topBitPosition)
topBitPosition++;
// Find a rough estimate of b ^ 1/4
unsigned long long x = b >> (topBitPosition - topBitPosition/4);
// Work down from there
while(x*x*x*x+x*x*x+x*x+x+1 > b)
x--;
cout<<"max value of x:"<<x-1<<endl;
Don't let x exceed 65535. If 65535 satisfies the inequality, 65536 will not.
Quick answer:
First af all you are starting from x=0 and then increasing it which is not the best solution since you are looking for the maximum value and not the first one.
So for that I would go from an upperbound that can be
x=abs((b)^(1/4))
than decrease from that value, and as soon you find an element <=b you are done.
You can even think in this way:
for y=b to 1
solve(x^4+x^3+x^2+x+1=y)
if has an integer solution then return solution
See this
This is a super quick answer I hope I didn't write too many stupid things, and sorry I don't know yet how to write math here.
Here's a slightly more optimized version:
#include<iostream>
int main()
{
std::cout << "Sorry, no value of x satisfies the inequality" << std::endl;
return 0;
}
Why? Because x^4+x^3+x^2+x+1 is unbounded as x approaches positive infinity. There is no b for which your inequality holds. Computer Science is a subset of math.

CUDA: reindexing arrays

In this example, I have 3 float arrays, query_points[], initial_array[], and final_array[]. Values in query_points[] are rounded down and become index values, and I want to copy the data at those indexes in initial_array[] to result_array[].
The problem I'm having is every few hundred values, I am getting different values compared to properly working c++ code. I am new to CUDA and not sure what is happening. Please let me know if you can point me towards a solution. Thanks!
CUDA Code:
int w = blockIdx.x * blockDim.x + threadIdx.x; // Col // width
int h = blockIdx.y * blockDim.y + threadIdx.y; // Row // height
int index = h*width+w;
if ((w < width) && (h < height)){
int piece = floor(query_points[index]) - 1;
int piece_index = h*width+piece;
result_array[index] = initial_array[piece_index];
}
You gave the answer in your own comment: "I also think it may have had to do with the fact that I was passing the same input and output array into the function, trying to do an in place operation."
Your description of the symptom (it only happens occasionally and it only repros on large arrays) also fits the explanation.
Note that it isn't always possible to guard against race conditions if you want full concurrency - you may have to use separate input and output arrays. Merge Sort and Radix Sort both ping-pong between intermediate arrays while processing. I don't think anyone has figured out how to implement those algorithms without O(N) auxiliary space.
I didn't write the code to test it but there are two problems that I can see:
If you are floor-ing a float than use floorf() function. I do not think this is the cause, but it is obviously the better way to do it.
The main issue that I can see is subtler, or maybe I am just speculating: floor() and floorf() return float and double respectively. So, when you do :
floor(query_points[index]) - 1;
what you have is still a float and might be smaller than the actual integral value you are supposed to get due to precision loss. When you implicitly cast it to integer by
int piece = floor(query_points[index]) - 1;
you basically truncate the decimal part and get n-1 where you think you are getting n.
Even without this analysis
int piece = floor(query_points[index]) - 1;
In this line, you are flooring and than truncating, which are essentially the same thing, so you do not even need to use floor() or floorf().

Randomly Generating a 2d/3d Array

I've thought about this for awhile but what is maybe a good way to go about randomly generating a 2-d or possibly 3-d array. Im not looking for specific code per se, but more just a general idea or way one might think of doing it.
edit: Sorry I mistyped, What I meant is say you have an array (2d or 3d) filled with empty space, and I wanted to randomly generate Char *'s in it......randomly(everything else would be blank). is what I meant.
create a 2D/3D array
Fill it with random data
?????
Profit!
If you were trying to sparsely fill a large 2D array with uppercase ASCII characters it would be something like the following in C:
int array[A][B];
for (int i = 0; i < SOMETHING; ++i)
{
//Note: Modulus will not give perfect random distributions depending on
//the values of A/B but will be good enough for some purposes.
int x = rand() % A;
int y = rand() % B;
char ch = rand() % 26 + 'A';
array[x][y] = ch;
}
Just generate a bunch of random values using rand() and arrange them into an array.
If you want the randomness to have continuity in 2 or 3 dimensions, the concept you're looking for is "noise".
I know you didn't want the whole code, but it's really not that much code.
int array[A][B][C];
std::generate_n(array[0][0], A*B*C, rand);
This is not the exact answer you asked for, but could prove useful anyway. Sometimes when I want to generate a large random string, I do the following:
1. generate a small random string, say 3 or 4 characters in length
2. get its hash with your algorithm of choice (MD5, SHA1, etc)
In this way you can generate quite long 'randoms' strings. Once you have the very long random string you can split it up into smaller ones or use it whole. The integrity of the randomness is based on how random the short initial string is.
This should work:
int *ary, /* Array */
x_size, /* X size of the array */
y_size; /* Y size of the array */
x = rand() % MAX_SIZE;
y = rand() % MAX_SIZE;
ary = malloc(sizeof(int) * (x * y));
ary[1][1] = 1;
If the [][] indexing doesn't work, you may need to use
*(ary + (x_size * X_COORD) + Y_COORD)
to access element [X_COORD][Y_COORD]. I'm not completely sure whether c99 supports that syntax.
Sorry, I couldn't think of a way to say it without code.
EDIT: Sorry for the confusion - thought you needed a random size array.

C++ program to calculate quotients of large factorials

How can I write a c++ program to calculate large factorials.
Example, if I want to calculate (100!) / (99!), we know the answer is 100, but if i calculate the factorials of the numerator and denominator individually, both the numbers are gigantically large.
expanding on Dirk's answer (which imo is the correct one):
#include "math.h"
#include "stdio.h"
int main(){
printf("%lf\n", (100.0/99.0) * exp(lgamma(100)-lgamma(99)) );
}
try it, it really does what you want even though it looks a little crazy if you are not familiar with it. Using a bigint library is going to be wildly inefficient. Taking exps of logs of gammas is super fast. This runs instantly.
The reason you need to multiply by 100/99 is that gamma is equivalent to n-1! not n!. So yeah, you could just do exp(lgamma(101)-lgamma(100)) instead. Also, gamma is defined for more than just integers.
You can use the Gamma function instead, see the Wikipedia page which also pointers to code.
Of course this particular expression should be optimized, but as for the title question, I like GMP because it offers a decent C++ interface, and is readily available.
#include <iostream>
#include <gmpxx.h>
mpz_class fact(unsigned int n)
{
mpz_class result(n);
while(n --> 1) result *= n;
return result;
}
int main()
{
mpz_class result = fact(100) / fact(99);
std::cout << result.get_str(10) << std::endl;
}
compiles on Linux with g++ -Wall -Wextra -o test test.cc -lgmpxx -lgmp
By the sounds of your comments, you also want to calculate expressions like 100!/(96!*4!).
Having "cancelled out the 96", leaving yourself with (97 * ... * 100)/4!, you can then keep the arithmetic within smaller bounds by taking as few numbers "from the top" as possible as you go. So, in this case:
i = 96
j = 4
result = i
while (i <= 100) or (j > 1)
if (j > 1) and (result % j == 0)
result /= j
--j
else
result *= i
++i
You can of course be cleverer than that in the same vein.
This just delays the inevitable, though: eventually you reach the limits of your fixed-size type. Factorials explode so quickly that for heavy-duty use you're going to need multiple-precision.
Here's an example of how to do so:
http://www.daniweb.com/code/snippet216490.html
The approach they take is to store the big #s as a character array of digits.
Also see this SO question: Calculate the factorial of an arbitrarily large number, showing all the digits
You can use a big integer library like gmp which can handle arbitrarily large integers.
The only optimization that can be made here (considering that in m!/n! m is larger than n) means crossing out everything you can before using multiplication.
If m is less than n we would have to swap the elements first, then calculate the factorial and then make something like 1 / result. Note that the result in this case would be double and you should handle it as double.
Here is the code.
if (m == n) return 1;
// If 'm' is less than 'n' we would have
// to calculate the denominator first and then
// make one division operation
bool need_swap = (m < n);
if (need_swap) std::swap(m, n);
// #note You could also use some BIG integer implementation,
// if your factorial would still be big after crossing some values
// Store the result here
int result = 1;
for (int i = m; i > n; --i) {
result *= i;
}
// Here comes the division if needed
// After that, we swap the elements back
if (need_swap) {
// Note the double here
// If m is always > n then these lines are not needed
double fractional_result = (double)1 / result;
std::swap(m, n);
}
Also to mention (if you need some big int implementation and want to do it yourself) - the best approach that is not so hard to implement is to treat your int as a sequence of blocks and the best is to split your int to series, that contain 4 digits each.
Example: 1234 | 4567 | 2323 | 2345 | .... Then you'll have to implement every basic operation that you need (sum, mult, maybe pow, division is actually a tough one).
To solve x!/y! for x > y:
int product = 1;
for(int i=0; i < x - y; i ++)
{
product *= x-i;
}
If y > x switch the variables and take the reciprocal of your solution.
I asked a similar question, and got some pointers to some libraries:
How can I calculate a factorial in C# using a library call?
It depends on whether or not you need all the digits, or just something close. If you just want something close, Stirling's Approximation is a good place to start.