Modulo operation on power function - c++

I am getting this error while performing modulo operation on power function.
invalid operands of types ‘int’ and ‘__gnu_cxx::__promote_2<int, int, double, double>::__type {aka double}’ to binary ‘operator%’
this is my piece of code.
#include <bits/stdc++.h>
using namespace std;
int main() {
int t, n;
cin >> t;
int i, j, sum = 0;
for (i = 0; i < t; i++) {
cin >> n;
for (j = 1; (n % pow(5, j)) == 0; j++)
sum = sum + (n / pow(5, j));
cout << sum;
}
return 0;
}

pow is returning a double, modulo can only operate on int. Throw in some explaining variables and this will become more obvious. The code will also be more readable and more performant.

Wrong Types
The compiler error message results from the fact that the pow routine routines a double type, but the % operator accepts only integer operands.
pow is a tempting routine to use for exponentiation, but it returns a floating-point type, and you generally should not mix floating-point and integer arithmetic, for reasons including:
There are considerable problems and subtleties in using floating-point arithmetic, including issues with handling rounding errors.
Some implementations of pow are deficient in that they return inexact answers when exact answers are representable in the double type. For example, pow(5, 3) might return a number slightly below 125, and then taking a remainder modulo that (or its truncation to an integer) would not give the result you want.
Better Method
One way to resolve the immediate problem is to replace pow with a routine of your own that raises an integer to a non-negative integer power simply by multiplying repeatedly. However, there is a better approach. Change these two lines:
for (j = 1; (n % pow(5, j)) == 0; j++)
sum = sum + (n / pow(5, j));
to this:
for (j = 1; n % 5 == 0; j++)
{
n /= 5;
sum = sum + n;
}
So, instead of repeatedly using a power of 5 (5, 25, 125,…) with n, we instead divide n by 5 repeatedly.
Other Issues
These changes will give code that does what the code in your question would do if pow returned an integer type, for cases where it would not overflow. However, I suspect there are other issues in your code and it does not compute what you intended.
I think it is most likely your assignment was to write a program that computes the number of trailing zeros in n! (n factorial) when written in decimal. The number of trailing zeros in n! is the exponent of the greatest power of 10 that divides n!. This power is determined by the factors of 5 that are available, because every trailing zero requires a factor of 2 and a factor of 5 (to make 10) in n!, but it is constrained by the factors of 5 because factors of 2 are plentiful.
Thus, 1!, 2!, 3!, and 4! have no trailing zeros because they have no factors of 5. 5! has one trailing zero, and so do 6!, 7!, 8!, and 9!. Then 10! has two trailing zeros, as we can see since 1•2•3•4•5•6•7•8•9•10 has two factors of 5. The trailing zeros increase to three at 15! and four at 20!. So far, the number of trailing zeros of n! is n/5, truncated to an integer. Then, at 25!, we add not one but two factors of 5, since 25 is 52. Now the number of trailing zeros is not n/5 but n/5 + n/5/5. With some thought, we can see that, in general, the number of trailing zeros of n! is n/5 + n/5/5 + n/5/5/5 + n/5/5/5/5 + …, ending where the term reaches zero.
If your program continued while n / 5j was not zero instead of when n modulo 5j was zero, it would calculate this sum. The similarity of your program to this calculation leads me to suspect that was the intent. If so, change the lines to:
for (j = 1; 0 < n; j++)
{
n /= 5;
sum = sum + n;
}
(I have phrased it this way for simplicity, but we can also see that, if n < 5, the final iteration of the loop adds nothing, so we can also change the loop condition from 0 < n to 5 <= n.)
Additionally, the sum is not reset when a new n is read. Remove the declaration of sum before the first for loop and insert int sum = 0; after the first for and before the second.
Generally, it is good practice not to declare things before you need them. So remove the declaration of n from the top of main and put it after the first for. Remove the declarations of i and j before the for loop and define each one in its for loop: for (int i = 0; i < t; i++) and for (int j = 1; 5 <= n; j++).
In cout << sum;, you probably want a new-line character: cout << sum << '\n'; or cout << sum << std::endl;.
Do not include <bits/stdc++.h>. Instead, including standard headers, such as <iostream> for this program.
Avoid using using namespace std;. Use std:: in your code (e.g., std::cin instead of cin) even though it requires more typing or be selective about taking a few specific things from namespaces, such as using std::cin; instead of the entire namespace. While this initially requires more work, it avoids programs and trains you to be better cognizant of what your program is using.

Like #Keynan mentioned, pow returns a double while % requires the argument to be int. To make it work, you can cast the result to int with either static_cast or C-style cast.
// static_cast
for (j = 1; (n % static_cast<int>(pow(5, j))) == 0; j++)
// c-style cast
for (j = 1; (n % (int)pow(5, j)) == 0; j++)
Related links:
Why isn't int pow(int base, int exponent) in the standard C++ libraries?

Related

How to multiply strings without overflow by c++?

I tried to solve Multiply Strings by c++ by this approach, but I cannot avoid integer overflow by change type from int to long long int or double. Python won't overflow, so my code works like below.
Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2, also represented as a string.
Python works:
class Solution:
def multiply(self, num1: str, num2: str) -> str:
n = len(num1) # assume n >= m
m = len(num2)
if n < m:
num1, num2 = num2, num1
n, m = m, n
product = 0
for i in range(1, m + 1):
multiplier = int(num2[m - i]) # current character of num2
sum_ = 0
for j in range(0, n): # multiply num1 by multiplier
multiplicand = int(num1[n - j - 1])
num = multiplicand * (10 ** j) * multiplier
sum_ += num
product += sum_ * (10 ** (i - 1))
return str(product)
C++ failed:
string multiply(string num1, string num2) {
int n = num1.size();
int m = num2.size();
if (n < m) {
std::swap(num1, num2);
std::swap(n, m);
}
long long int product = 0;
for (int i = 1; i <= m; ++i) {
int multiChar = num2[m - i] - '0';
long long int sum = 0;
for (int j = 0; j < n ; ++j) {
int charCand = num1[n - j - 1] - '0';
long long int num = charCand * ((pow(10, j))) * multiChar;
sum += num;
}
product += sum * ((pow(10, i - 1)));
}
return std::to_string(product);
}
As far as I have tested, some cases are OK, but overflow seems unavoidable if the number is too big. Is there any way to fix my code?
Testcase:
"12323247989"
"98549324321"
runtime error: 1.05355e+20 is outside the range of representable values of type 'long long' (solution.cpp)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:28:17
Expected:
"1214447762756072040469"
You are not on the right way. Imagine how you would do that by hand:
abc*def
-------
xxxx
xxxx0
xxxx00
-------
You just add single digits as well, don't you? Only those of same significance – possibly considering some carry.
You might rather reproduce the same in code, too. Producing overflow that way is much less likely (I assume that after multiplying single digits summing up the results in a single integer – recommending an unsigned type for – is acceptable; if not, you'd have to build up a std::string again). The sign you calculate independently, just as you'd do by hand as well.
One difference to multiplication by hand we'll have, though: By hand you would create rather large intermediate numbers by multiplying one number with each digit
of the other number. That would require to store these intermediate numbers as strings again, e. g. in a vector. More efficient, though, is identifying those digit pairs of which the multiplication results in the same significance.
These will be 0|0 -> 0; 0|1, 1|0 -> 1; 0|2, 1|1, 2|0 -> 2, and so on. You produce these pairs by:
for(size_t i = 0, max = std::max(num1.length(), num2.length); i < max; ++i)
{
for(size_t j = 0; j < i; ++j)
{
if(j < num1.length() && i - j < num2.length())
{
// iterate backwards for easy carry handling
size_t idx1 = num1.length() - j;
size_t idx2 = num2.length() - (i - j);
// multiply characters at num1[idx1] and num2[idx2] and add result to sum
}
}
// add carry
// calculate last digit and a p p e n d to a result string
// update carry
}
// append '-' sign, if result is negative
std::reverse(result.begin(), result.end());
Building up the string in reverse order is more efficient, as you do not need to move the subsequent characters all the time. (Untested code, if you find a bug, please fix it yourself).
The loops are in my preferred variant; if you feel better with another, feel free to change; just be aware that with signed types you can produce endless loops if you try e. g. for(unsigned i = n; n >= 0; --i /* overflows to UINT_MAX */).
Side note: You should accept the input strings by reference (std::string const& num1, std::string const& num2), that avoids the needless copies arising by accepting by value.

Is there a more efficient way of checking if an element is inside given intervals?

Suppose I have a variable x (double) that lies between 0 and 100. If x is in any of the intervals (0+10*n,5+10*n), with n (int) =0,...,9, then I return n, otherwise I break. I was thinking of doing this
bool test = false;
int k;
for(int i=0; i<10; i++){
if((0+10*i)<x<(5+10*i)){
k = i;
test = true;
}
}
if(test) return k;
else break;
would this be correct? If so, is there any other way that avoids loops?
It depends which intervals you have in mind. Since your intervals have a pattern to them, you can use a mathematical formula instead of a loop:
if(((int)x % 10) < 5) return (int)(x / 10);
else break;
(The % here is the modulo operator.)
Since C++'s % operator doesn't work on doubles, you can either cast x to an integer (as shown), or use the fmod function (works for non-integer intervals).
you can use % operator to get it's mod. get x % 10 and check if result of mod between 0 and 5. it can be faster than that.

Task on the number of iterations

There is a number N
every iteration it becomes equal to (N*2)-1
I need to find out how many steps the number will be a multiple of the original N;
( 1≤ N ≤ 2 · 10 9 )
For example:
N = 7; count = 0
N_ = 7*2-1 = 13; count = 1; N_ % N != 0
N_ = 13*2-1 = 25; count = 2; N_ % N != 0
N_ = 25*2-1 = 49; count = 3; N_ % N == 0
Answer is 3
if it is impossible to decompose in this way, then output -1
#include <iostream>
using namespace std;
int main(){
int N,M,c;
cin >> N;
if (N%2==0) {
cout << -1;
return 0;
}
M = N*2-1;
c = 1;
while (M%N!=0){
c+=1;
M=M*2-1;
}
cout << c;
return 0;
}
It does not fit during (1 second limit). How to optimize the algorithm?
P.S All the answers indicated are optimized, but they don’t fit in 1 second, because you need to change the algorithm in principle. The solution was to use Euler's theorem.
The problem, as other answers have suggested, is equivalent to finding c such that pow(2, c) = 1 mod N. This is impossible if N is even, and possible otherwise (as your code suggests you know).
A linear-time approach is:
int c = 1;
uint64_t m = 2;
while (m != 1){
c += 1;
m = (2*m)%N;
}
printf("%d\n", c);
To solve this in 1 second, I don't think you can use a linear-time algorithm. The worst cases will be when N is prime and large. For example 1999999817 for which the above code runs in around 10 seconds on my laptop.
Instead, factor N into its prime factors. Solve 2^c = 1 mod p^k for each prime factor (where p^k appears in the prime factorization of N. Then combine the results using the Chinese Remainder theorem.
When finding the c for a given prime power, if k=1, the solution is c=p-1. When k is larger, the details are quite messy, but you can find a written solution here: https://math.stackexchange.com/questions/1863037/discrete-logarithm-modulo-powers-of-a-small-prime
The problem is that you're overflowing, the int data type only has 32 bits, and overflows 2^31-1 , in this problem you don't need to keep the actual value of M, you can just keep the modulo of n.
while (M%N!=0){
c+=1;
M=M*2-1;
M%=N
}
Edit:In addition, you don't actually need more than N iterations to check if a 0 mod exists, as there are only N different mods to N and it just keeps cycling. so you also need to keep that in mind in case there is no 0 mod.
There is no doubt that the main problem with your code is signed integer overflow
I added a print of M whenever M was changed (i.e. cout << M << endl;) and gave it the input 29. This is what I got:
57
113
225
449
897
1793
3585
7169
14337
28673
57345
114689
229377
458753
917505
1835009
3670017
7340033
14680065
29360129
58720257
117440513
234881025
469762049
939524097
1879048193
-536870911
-1073741823
-2147483647
1
1
1
1
... endless loop
As you see you have signed integer overflow. That is undefined behavior in C so anything may happen!! On my machine I ended up with a nasty endless loop. That must be fixed before considering performance.
The simple fix is to add a line like
M = M % N;
whenever M is changed. See the answer from #Malek
Besides that you shall also use an unsigned integer, i.e. use uint32_t for all variables.
However, that will not improve performance.
If you still have performance issue after the above fix, you can try this instead:
uint32_t N;
cin >> N;
if (N%2==0) {
cout << -1;
return 0;
}
// Alternative algorithm
uint32_t R,c;
R = 1;
c = 1;
while (R != N){
R = 2*R + 1;
if (R > N) R = R - N;
++c;
}
cout << c;
On my laptop this algorithm is 2.5 times faster when testing on all odd numbers in the range 1..100000. However, it might not be sufficient for all numbers in the range 1..2*10^9.
Also notice the use of uint32_t to avoid integer overflow.

Converting from Decimal to BCD

// C++ program to convert a decimal
// number to binary number
#include <iostream>
using namespace std;
// function to convert decimal to binary
void decToBinary(int n)
{
// array to store binary number
int binaryNum[1000];
// counter for binary array
int i = 0;
while (n > 0) {
// storing remainder in binary array
binaryNum[i] = n % 2;
n = n / 2;
i++;
}
// printing binary array in reverse order
for (int j = i - 1; j >= 0; j--)
cout << binaryNum[j];
}
// Driver program to test above function
int main()
{
int n = 17;
decToBinary(n);
return 0;
}
So this is a program to convert Decimal numbers to Binary. Now I'm trying to convert Decimal Numbers to BCD. I get the concept, if I have a number like 215 for example, I separate each number [2,1,5] and then convert each number into binary so it would be 0010,0001,0101. I am just confused about implementing it.
First of all, your algorithm simply displays the binary representation of some number n, instead of dividing it into single digits and returning some set of their binary representation.
To make out lives easier, we will be using standard containers and standard algorithms:
[...] if i have a number like 215 for example, i seperate each number [2,1,5] and then covert each number into binary so it would be 0010,0001,0101
Great, it means that we need some sort of a container to hold those three representations, don't we? My choice would be std::vector, since it is incredibly simple and efficient! You can read more about it here.
The mentioned vector will eventually store the binary representations, but here we encounter another problem - we actually need to somehow represent them!
Fortunately enough, the standard gives us a great tool - std::bitset, which is explained here. It is primarily used to make binary operations easier, but one of its great features is that it's also extremely good at simply being a binary representation.
The final function could look like this:
auto dec_to_bin(int n)
{
std::vector<std::bitset<4>> repr;
while(n > 0){
repr.push_back(std::bitset<4>(n % 10));
n /= 10;
}
std::reverse(repr.begin(), repr.end());
return repr;
}
What is happening here?
We firstly create a vector of fixed size bitsets (of the size 4, since every decimal digit can be represented as four binary digits), then as long as our n is greater than zero (you already know why - you are using the same logic in your code), we add (using push_back) a new bitset, that will be treated as binary representation of modulo of your number (i.e. the last digit).
Keep in mind though, that by doing this, we created the vector in the reversed order. The last two things we have to do is simply reverse and return it!
Finally, we can use our function in main as such:
int main()
{
for(auto b : dec_to_bin(215)){
std::cout << b << ' ';
}
}
This will print 0010 0001 0101, which was your desired output for the number 215
Can't you just replace the % 2 and / 2 with % 10 and / 10? The variables will be named wrong but that's the algorithmic change.
You simply have to divide your integer by digits and call your function for each digit:
void decToBCD(int n) {
// array to store digits
int digits[10];
// counter for digits
int i = 0;
while (n > 0) {
// storing remainder in digit array
digits[i] = n % 10;
n = n / 10;
i++;
}
// printing binary representation of digits
for (int j = i - 1; j >= 0; j--) {
decToBinary(digits[j]);
cout << " ";
}
}
I would update what you have to return a string from decToBinary rather than printing to cout, you can then write decToBCD which uses modulo 10 to work out the integer for each digit of the number (in the same way you used modulo 2 and divide by 2 to get each bit in decToBinary), and call decToBinary for each integer digit and concatenates the strings of binary digits to give the full result.

how to find out the number of digits of a number in c++?

I wanna find out the number of digits of a number in c++ but I don't know what can I do? for example number of digits 7676575.
Take the ceiling of the base-10 logarithm of the number. (Or more generally "base-N" for the number of digits in base N.)
In code: std::ceil(std::log10(n + 1)), and make sure to #include <cmath>.
(You'll get the answer 0 for input 0 as a special case. It's up to you what to do about negative numbers.)
The code in #Knaģis's answer is possibly more efficient, since divisions by the constant 10 can be turned into multiplications by the compiler and are fairly cheap. You have to profile and compare if this is per­formance-critical, and if this applies to integral types only. The logarithm approach also lets you com­pute the number of digits in a hypothetical decimal expansion of very large floating point numbers.
int i = 7676575;
int digits = i == 0 ? 1 : 0;
i = abs(i); // handle negative numbers as well
while (i > 0)
{
digits++;
i /= 10;
}
// -or- if you prefer do/while then a shorter sample (by Kerrek SB)
int i = 7676575;
int digits = 0;
i = abs(i); // handle negative numbers as well
do { digits++; } while (i /= 10);
Just put it in a string and get its length;
int number = getNumberFromSomewhere();
stringstream ss;
ss << number;
size_t numDigits = ss.str().length();
template <typename T>
int getdigits(T v)
{
T i = std::abs(v);
if (i < 10) return 1;
else if (i < 100) return 2;
...
else if (i < 100000000) return 8;
else if (i < 1000000000) return 9;
}
And so on, you can extend to include long range, not only int. I'm not sure if this is faster than divide, but why not - it's just 10 comparisons.
I suppose templates black magic can be used to generate functions with only needed number of ifs, but who really cares. But you can ensure T is integer using std::enable_if<std::is_integer<T>::value>.
You can convert to string and check the length of the string:
std::to_string(number).size()