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.