Неправильные типы
Сообщение об ошибке компилятора является следствием того факта, что подпрограмма pow
имеет тип double
, но оператор %
принимает только целочисленные операнды.
pow
- это заманчивая процедура, используемая для возведения в степень, но она возвращает тип с плавающей запятой, и, как правило, не следует смешивать арифметику с плавающей запятой и целочисленную арифметику c по следующим причинам:
- Там Существенные проблемы и тонкости в использовании арифметики с плавающей точкой c, включая проблемы с обработкой ошибок округления.
- Некоторые реализации
pow
несовершенны, так как возвращают неточные ответы, когда точные ответы представимы в double
тип. Например, pow(5, 3)
может вернуть число чуть ниже 125, а затем взять остаток по модулю, который (или его усечение до целого числа) не даст желаемого результата.
Лучший метод
Один из способов решения насущной проблемы - заменить pow
собственной процедурой, которая возводит целое число в неотрицательную целочисленную степень просто путем многократного умножения. Тем не менее, есть лучший подход. Измените эти две строки:
for (j = 1; (n % pow(5, j)) == 0; j++)
sum = sum + (n / pow(5, j));
на эту:
for (j = 1; n % 5 == 0; j++)
{
n /= 5;
sum = sum + n;
}
Таким образом, вместо многократного использования степени 5 (5, 25, 125, ...) с n
, вместо этого мы делим n
на 5 раз.
Другие проблемы
Эти изменения дадут код, который будет делать то же, что и код в вашем вопросе, если pow
вернул целочисленный тип, для случаев где это не будет переполнено. Однако, я подозреваю, что в вашем коде есть другие проблемы, и он не вычисляет то, что вы хотели.
Я думаю, что наиболее вероятно, что ваше назначение было написать программу, которая вычисляет количество конечных нулей в п ! ( n факториал) при десятичной записи. Количество конечных нулей в n ! является показателем величайшей степени 10, которая делит n !. Эта мощность определяется коэффициентами 5, которые доступны, потому что для каждого завершающего нуля требуется коэффициент 2 и коэффициент 5 (чтобы сделать 10) в n !, но он ограничен факторами 5, потому что множителей 2 много.
Таким образом, 1 !, 2 !, 3 !, и 4! не имеют конечных нулей, потому что они не имеют коэффициентов 5. 5! имеет один завершающий ноль, как и 6 !, 7 !, 8 !, и 9 !. Тогда 10! имеет два запаздывающих нуля, как мы видим, поскольку 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 имеет два фактора по 5. Задние нули увеличиваются до трех при 15! и четыре в 20 !. Пока что число конечных нулей составляет n ! n / 5, усеченное до целого числа. Затем в 25 !, мы добавляем не один, а два фактора из 5, поскольку 25 равно 5 2 . Теперь число конечных нулей не n / 5, а n / 5 + n / 5/5. Подумав немного, мы видим, что, как правило, число конечных нулей составляет n ! n / 5 + n / 5/5 + n / 5/5/5 + n / 5/5/5 / 5 +…, заканчивающийся там, где термин достигает нуля.
Если ваша программа продолжалась, в то время как n / 5 j не было нулем вместо когда n по модулю 5 j равняется нулю, он вычисляет эту сумму. Сходство вашей программы с этим расчетом заставляет меня подозревать, что это было намерение. Если это так, измените строки на:
for (j = 1; 0 < n; j++)
{
n /= 5;
sum = sum + n;
}
(я сформулировал это для простоты, но мы также можем видеть, что, если n <5, последняя итерация l oop ничего не добавляет, поэтому мы также можем изменить условие l oop с <code>0 < n на 5 <= n
.)
Кроме того, сумма не сбрасывается при чтении нового n
. Удалите объявление sum
перед первым for
l oop и вставьте int sum = 0;
после первого for
и перед second
.
Как правило, рекомендуется не объявлять вещи, прежде чем они вам нужны. Поэтому удалите объявление n
с вершины main
и поместите его после первого for
. Удалите объявления i
и j
перед for
l oop и определите каждое в его for
l oop: for (int i = 0; i < t; i++)
и for (int j = 1; 5 <= n; j++)
.
In cout << sum;
, вам, вероятно, нужен символ новой строки: cout << sum << '\n';
или cout << sum << std::endl;
.
Не включать <bits/stdc++.h>
. Вместо этого, включая стандартные заголовки, такие как <iostream>
для этой программы.
Избегайте использования using namespace std;
. Используйте std::
в своем коде (, например, , std::cin
вместо cin
), даже если это требует большего набора текста или выбора при выборе нескольких определенных c вещей из пространств имен, таких как using std::cin;
вместо всего пространства имен. Хотя изначально это требует больше работы, оно избегает программ и обучает вас лучше понимать, что использует ваша программа.