This question already has answers here:
Calculate a*a mod n without overflow
(5 answers)
Closed 7 years ago.
I have a code that contains statements like
ans =((ans % mod)*(n % mod)) % mod;
and,
inverse= findMMI_fermat(n,mod);
ans =((ans % mod)*(inverse % mod)) % mod;
findMMI_fermat is defined as:
ull fast_pow(ull base,ull n,ull M) //ull is unsigned long long
{
if(n==0)
return 1;
if(n==1)
return base;
ull halfn=fast_pow(base,n/2,M);
if(n%2==0)
return ( halfn * halfn ) % M;
else
return ( ( ( halfn * halfn ) % M ) * base ) % M;
}
ull findMMI_fermat(ull n,ull M)
{
return fast_pow(n,M-2,M);
}
All the variables are declared unsigned long long. The program is running fine till size of ans,mod and n all grow to the order of 10^18. I know that I can't multiply such large numbers directly and I know an approach of converting the integers to string and then multiplying them. But is there any other easier way?
No, there isn't. the other approach needs work too. but, does not use strings. it uses array of bytes or array of integers or long long.
But, it works exactly as the strings approach work.
Languages as Java have a built in library for big numbers. I don't recall such a library for c++.
Related
I am currently practicing algorithms and DS. I have stumbled upon a question that I can't figure out how to solve. So the question's link is there:
In summary, it says that there is a number of chairs in a circle, and the position of the person (relative to a certain chair), and how many M movements he should make.
So the input is as following:
3 integer numbers N, M, X , The number of chairs, the number of times the boy should move and the first chair he will start from respectively ( 1 ≤ X ≤ N < 2^63 , 0 ≤ M < 2^63 )
So, what have I done so far? I thought about the following:
So I thought that the relative position after M movements is (x+m) % n, and since this can cause Integer overflow, I have done it like that, ((x%n) + (m%n)) % n. I have figured out that if the person has reached the last index of chair, it will be 0 so I handled that. However, it passes only 2 tests. I don't need any code to be written, I want to directed in the right way of thinking. Here is my code so far:
#include <iostream>
using namespace std;
int main() {
long long n, m, x;
cin >> n >> m >> x;
// After each move, he reaches (X+1).
// X, N chairs.
// ((X % N) + (M % N)) % N;
// Odd conideration.
if ( m % 2 == 1) {
m += 1;
}
long long position = (x % n + m % n) % n;
if (position == 0) {
position = n;
}
cout << position;
return 0;
}
If the question required specific error handling, it should have stated so (so don't feel bad).
In every real-world project, there should be a standard to dictate what to do with weird input. Do you throw? Do you output a warning? If so, does it have to be translated to the system language?
In the absence of such instructions I would err toward excluding these values after reading them. Print an error to std::cerr (or throw an exception). Do this as close to where you read them as possible.
For overflow detection, you can use the methods described here. Some may disagree, and for a lab-exercise, it's probably not important. However, there is a saying in computing "Garbage in == Garbage out". It's a good habit to check for garbage before processing, rather than attempting to "recycle" garbage as you process.
Here's the problem:
Say the value of N is 2^63-1, and X and M are both 2^63 - 2.
When your program runs untill the ((X % N) + (M % N)) % N part,
X % N evaluates into 2^63 - 2 (not changed), and so does M % N.
Then, the addition between the two results occurs, 2^63 - 2 + 2^63 - 2 there is the overflow happening.
After the comment of #WBuck, the answer is actually rather easy which is to change the long long to unsigned because there are no negative numbers and therefore, increase the MAX VALUE of long long (when using unsigned).
Thank you so much.
input : integer ( i'll call it N ) and (1 <= N <= 5,000,000 )
output : integer, multiple of N and only contains 0,7
Ex.
Q1 input : 1 -> output : 7 ( 7 mod 1 == 0 )
Q2 input : 2 -> output : 70 ( 70 mod 2 == 0 )
#include <string>
#include <iostream>
using namespace std;
typedef long long ll;
int remaind(string num, ll m)
{
ll mod = 0;
for (int i = 0; i < num.size(); i++) {
int digit = num[i] - '0';
mod = mod * 10 + digit;
mod = mod % m;
}
return mod;
}
int main()
{
int n;
string ans;
cin >> n;
ans.append(n, '7');
for (int i = ans.length() - 1; i >= 0; i--)
{
if (remaind(ans, n) == 0)
{
cout << ans;
return 0;
}
ans.at(i) = '0';
}
return 0;
}
is there a way to lessen the time complexity?
i just tried very hard and it takes little bit more time to run while n is more than 1000000
ps. changed code
ps2. changed code again because of wrong code
ps3. optimize code again
ps4. rewrite post
Your approach is wrong, let's say you divide "70" by 5. Then you result will be 2 which is not right (just analyze your code to see why that happens).
You can really base your search upon numbers like 77777770000000, but think more about that - which numbers you need to add zeros and which numbers you do not.
Next, do not use strings! Think of reminder for a * b if you know reminder of a and reminder of b. When you program it, be careful with integer size, use 64 bit integers.
Now, what about a + b?
Finally, find reminders for numbers 10, 100, 1000, 10000, etc (once again, do not use strings and still try to find reminder for any power of 10).
Well, if you do all that, you'll be able to easily solve the whole problem.
May I recommend any of the boost::bignum integer classes?
I suspect uint1024_t (or whatever... they also have 128, 256, and 512, bit ints already typedefed, and you can declare your own easily enough) will meet your needs, allowing you to perform a single %, rather than one per iteration. This may outweigh the performance lost when using bignum vs c++'s built-in ints.
2^1024 ~= 1.8e+308. Enough to represent any 308 digit number. That's probably excessive.
2^512 ~= 1.34e+154. Good for any 154 digit number.
etc.
I suspect you should first write a loop that went through n = 4e+6 -> 5e+6 and wrote out which string got the longest, then size your uint*_t appropriately. If that longest string length is more than 308 characters, you could just whip up your own:
typedef number<cpp_int_backend<LENGTH, LENGTH, unsigned_magnitude, unchecked, void> > myReallyUnsignedBigInt;
The modulo operator is probably the most expensive operation in that inner loop. Performing once per iteration on the outer loop rather than at the inner loop (O(n) vs O(n^2)) should save you quite a bit of time.
Will that plus the whole "not going to and from strings" thing pay for bignum's overhead? You'll have to try it and see.
This question already has answers here:
C++ - how to find the length of an integer
(17 answers)
Closed 7 years ago.
In Java, I use
int length = String.valueOf(input).length();
to find the length of an integer.
My question is: Are there any similar ways to do so in C++?
I have already tried the for loops and while loops such as:
while (input > 0){
input/=10;
count++;
So, apart from the loops are there anything else available in C++. Thank you for your answer.
If you want an exact counterpart of what you have written in Java, you can use:
int length = to_string(input).length();
Note that to_string is a C++11 feature. Also, be careful with negative numbers.
The number of digits can be calculated without converting to a string first by using the number's logarithm:
std::size_t intlen(int i) {
if (i == 0) return 1;
else if (i < 0) return 2 + static_cast<std::size_t>(std::log10(-i));
else if (i > 0) return 1 + static_cast<std::size_t>(std::log10(i));
}
The logartihm is only defined for positive numbers, so negatives and zero have to be handled separately, counting the - sign as an additional character. Replace log10 by log2 to obtain the number of binary digits (this is possible for any base).
Note however that converting to strings first (e.g. by using std::to_string) is a locale-dependent operation and can thus yield different results for different language settings - some locales insert a thousands separator (e.g. 100,000) which will not show up using the above formula.
unsigned int number_of_digits = 0;
do {
++number_of_digits;
n /= base; } while (n);
// n is your base number.
Talking about pre-C++11, you can use the same approach, but with sprintf.
Convert integer to a char array, and then get its length:
char buffer[30];
int length = sprintf(buffer, "%d", input);
Here is the working IDEOne example.
Apart from the loops there is recursion. For example, for positive integers you can do:
unsigned int len(unsigned int n)
{
return n ? len(n/10)+1 : 0;
}
What is the need of the statement ans = (ans + mod) % mod in this program ?
Assume that mod = 10^9+7. This function is computing a to the power of b under mod operation in O(log(n)) complexity:
long long power(long long a, long long b)
{
if (b == 0)
return 1ll;
long long ans = power(a, b/2);
ans = (ans * ans) % mod;
ans = (ans + mod) % mod;
if(b % 2 == 1)
ans = (ans * a) % mod;
ans = (ans + mod) % mod;
return ans;
}
The most common usage of such a construct is to make sure the result is non-negative. The standard operator% behaves differently for positive and negative arguments: for example, 4%3==1, but (-2)%3==-2, while you might expect (-2)%3==1 and (-2)/3==-1, which is mathematically more correct.
This behavior can often cause problems when modular arithmetic is used, and this trick of adding mod is often employed to obtain the mathematically more correct non-negative result. Instead of simply writing a%b, if a can be negative, one writes (a%b+b)%b.
However, its usage in the code in your question is strange. In that case, it is easier to assume that a is positive before calling the power function from the main code (for example, by making the main call like power((a%mod+mod)%mod, b)). Probably the author just wanted to get additional assurance of correctness, although it was not needed.
In my short sports programming career i encountered many time Calculating mod of numbers like
26164615615665561165154564545......%(10000007)
I have done some research but could only find calculation of mods of numbers in the form
(a^b)%c
can anybody explain how to calculate mod of numbers like the first example.
C++ does not have any long integer arithmetic facilities as part of the standard library.
If you want to compute with long integers, you need to rely on an external library.
Two good choices seem to be
GMP: https://gmplib.org - if you are not afraid of C-like interface (there is also gmpxx though)
NTL: http://www.shoup.net/ntl/ - my personal favourite, provides clear and easy interface (e.g. class ZZ for long integers and ZZ_p for long integers modulo)
Here is an example (taken from NTL examples) of how a modular exponentiation could be done using NTL:
ZZ PowerMod(const ZZ& a, const ZZ& e, const ZZ& n)
{
if (e == 0) return ZZ(1);
long k = NumBits(e);
ZZ res;
res = 1;
for (long i = k-1; i >= 0; i--) {
res = (res*res) % n;
if (bit(e, i) == 1) res = (res*a) % n;
}
if (e < 0)
return InvMod(res, n);
else
return res;
}
I have found the solution(maybe)
So,here goes explaination.If we want to calculate mod of very big numbers that cannot be stored as any data type than we have to take number as a string.Than we will do something like this
int remainder(string &s,first)
{
int rem=0;
for(int i=0;i<s.length();++i)
rem=rem*10+(s[i]-'0');//Explaining this below
return rem;
}
Why does it work ?Take a paper and pen and start doing division of string with the number first(taking 100) for ease.
For example, for 1234 % 100.
1 mod 100 = 1
12 mod 100 =(1 * 10 + 2) mod 100 =12
123 mod 100 =(12 * 10 + 3) mod 100 =23
1234 mod 100 =(23 * 10 + 4) mod 100 =34
PS:This is my first answer.Sorry i wrote answer to my own question but i thought it would be good for future readers.