Можно ли использовать Math.Pow(10, n)?
Мне нужно вычислить мощность (10, n)
Можно ли использовать Math.Pow (10, n)
?
Или использовать цикл?
for (int i = 0; i < n; i++){
x*=10;
}
Какой из них лучше? и почему?
Ответы
Ответ 1
Если базовые и экспоненты являются целыми числами, вы можете не использовать Pow. Но даже в этом случае Пау обычно лучше, потому что это более читаемо. Если хотя бы одно значение является плавающей точкой, используйте параметр Pow.
Если показатель степени равен 0,5, вы должны использовать Sqrt, а если показатель представляет собой небольшое целое число (2,3,4), выражающее формулу с умножениями, это быстрее, но менее читаемо.
Если вы хотите реализовать быстрое экспонирование с помощью целочисленного показателя, то алгоритм Square-and-Multiply, а не простой цикл может быть тем, что вы хотите. Но в большинстве сценариев Pow еще быстрее.
Ответ 2
Math.Pow
лучше.
Здесь практическое правило - в 99% сценариев предпочтение встроенных функций предпочтительнее пользовательских реализаций. Это делает ваш код более понятным, экономит много работы и снижает вероятность ошибок.
Только тогда, когда вы думаете об использовании встроенных функций способами, которые они не предназначены для использования, или когда они имеют серьезные проблемы с задержкой (никогда, честно говоря, никогда не сталкивались с этими сценариями), вам следует подумать о создании собственной реализации.
Ответ 3
Для целых чисел, возможно, цикл for быстрее, чем Math.Pow
, который, вероятно, имеет дело с числами с плавающей запятой. Но я серьезно сомневаюсь, что разница в вашем случае значительна (хотя я этого не знаю).
Но если вы работаете с 32-разрядными целыми знаками, то вы можете хранить только значения 10 ^ n для n <= 9. Но тогда вы получите скорость (и, возможно, читаемость), сохранив эти девять (десять) силы десяти в массиве. Это не сложно: они (1), 10, 100, 1000,....
Если вам нужно вычислить 10 ^ n для большего n, вам нужно использовать числа с плавающей запятой. И тогда нет никакой причины использовать Math.Pow
. Это быстро и легко читается.
Ответ 4
Зависит от того, что более четко сообщается "10 с силой n".
В моем случае Math.Pow(10, n)
(хотя это может означать математику, коллективно штамповка 10 и n в их лицах, а также, я не знаю).
Это похоже на то, как я предпочел бы алгебраически выразить "10 до степени n" как 10^n
(или 10n
), чем 10 * 10 * 10 * ... * 10 n times
, особенно учитывая, что n является переменной.
Ответ 5
Ответ обычно будет да, используйте Math.Pow().
Однако: если этот код действительно критичен по времени, и вы знаете, что имеете дело с малыми мощностями 1-9, поэтому результат может быть выражен в Int32, тогда его можно оптимизировать. Я просто сделал быстрое тестовое приложение и профилировал две версии (убедившись, что компилятор не оптимизировал код), а результат на моем ноутбуке в худшем случае 10 ^ 9 заключался в том, что цикл был 20 раз быстрее, чем Math.Pow(10,9).
Но, пожалуйста, помните, может быть, этот расчет на самом деле не является узким местом. Если вы знаете, что это так, например, если вы профилировали свое приложение и обнаружили, что это настоящая проблема, тогда перейдите к нему и замените его на метод, основанный на петле (или, что еще лучше, на поиск массива). Если вы просто догадываетесь, что это может быть проблемой, я бы посоветовал вам придерживаться Math.Pow. В общем: оптимизировать код, который, как вы знаете, является узким местом производительности.
Ответ 6
Math.Pow предоставляется для вас и хорошо документирована.
Любые ошибки содержатся в документации.
Почему вы не хотите использовать предоставленную функцию?
Ответ 7
Есть гораздо более производительные реализации целочисленного Pow, чем умножение на 10 в цикле.
Посмотрите этот ответ, например, он также работает для других базовых значений, а не только для 10.
Кроме того, рассмотрите результаты кэширования, вплоть до разумного количества, в массиве.
Вот мой недавний код, для справки:
private static readonly Int64[] PowBase10Cache = {
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000,
10000000000,
100000000000,
1000000000000,
10000000000000,
100000000000000,
1000000000000000,
10000000000000000,
100000000000000000,
1000000000000000000,
};
public static Int64 IPowBase10(int exp)
{
return exp < PowBase10Cache.Length ? PowBase10Cache[exp] : IPow(10L, exp);
}
public static Int64 IPow(Int64 baseVal, int exp)
{
Int64 result = 1;
while (exp > 0)
{
if ((exp & 1) != 0)
{
result *= baseVal;
}
exp >>= 1;
baseVal *= baseVal;
}
return result;
}
Ответ 8
Да, нормально использовать Math.Pow()
.