Быстрый способ вычислить n раз 10 возведенных в степень минус м - PullRequest
2 голосов
/ 27 мая 2011

Я хочу вычислить 10 в степени минус m.В дополнение к использованию математической функции pow(10, -m), есть ли быстрый и эффективный способ сделать это?

Что я задаю столь простой вопрос гуру c ++ из SO, так это то, что, как вы знаете, так же, какБаза 2, 10 также является специальной базой.Если какое-либо значение n умножить на 10-кратную степень минус m, это эквивалентно перемещению десятичной точки n влево m раз.Я думаю, что это должен быть быстрый и эффективный способ справиться.

Ответы [ 9 ]

5 голосов
/ 27 мая 2011

Для числа с плавающей точкой m, если ваша стандартная реализация библиотеки хорошо написана, тогда pow будет эффективным.

Если m целое число, и вы намекнули, что это так, то вы можете использоватьмассив предварительно вычисленных значений.

Вы должны беспокоиться об этом только в том случае, если эта подпрограмма является узким местом в вашем коде.Это если вызовы этой подпрограммы занимают значительную долю общего времени выполнения.

4 голосов
/ 27 мая 2011

Десять - это не специальное значение на двоичной машине, только два. Используйте pow или возведение в степень в квадрате .

2 голосов
/ 27 мая 2011

К сожалению, нет быстрого и эффективного способа его вычисления с использованием представления с плавающей точкой IEEE 754.Самый быстрый способ получить результат - создать таблицу для каждого значения m, которое вас волнует, а затем просто выполнить поиск.

0 голосов
/ 17 декабря 2017

Если m целое число, просто вычислите 10 ^ m и вычислите обратное (1/10 ^ m). Использование возведения в степень по квадрату времени будет пропорционально log2 (м). При использовании числа с плавающей запятой max m будет близко к 1000, так что вы можете просто предварительно вычислить возведение в квадрат, возведя в квадрат и использовать справочную таблицу.

0 голосов
/ 27 мая 2011

Еще несколько идей, которые могут привести вас к дальнейшим решениям ...

  1. Если вы заинтересованы в оптимизация на уровне алгоритма вы может искать параллельное подход.

  2. Вы можете ускорить системный / архитектурный уровень по использованию Ipp (для процессоров Intel) или, например, AMD Базовая математическая библиотека (ACML) для AMD

  3. Чтобы использовать всю мощь вашей графики карта может быть другим способом (например, CUDA для карт NVIDEA)

  4. Думаю, стоит посмотреть OpenCL

0 голосов
/ 27 мая 2011

Если бы вы могли работать с log n вместо n в течение значительного времени, вы могли бы сэкономить время, потому что вместо

n = pow(10*n,-m)

вам теперь нужно вычислить (используя определение l = log10 (n))

l = -m*(l+1)
0 голосов
/ 27 мая 2011

IEEE 754 определяет набор форматов с плавающей запятой.Те, которые широко используются, являются двоичными, что означает, что база 10 не является чем-то особенным.Это противоречит вашему предположению, что «10 - это тоже особая база».

Интересно, что IEEE 754-2008 добавляет десятичные форматы с плавающей запятой (decimal32 и друзья).Тем не менее, мне еще не приходилось сталкиваться с аппаратными реализациями этих программ.

В любом случае вам не следует микрооптимизировать свой код, прежде чем вы его профилировали и установили, что это действительно узкое место.

0 голосов
/ 27 мая 2011

Использование таблицы поиска не может быть более 1000 с плавающей запятой, особенно если m целое число.

0 голосов
/ 27 мая 2011

Если есть быстрый и эффективный способ сделать это, то я уверен, что ваш процессор поддерживает его, если только вы не работаете на встроенной системе, в этом случае я бы надеялся , что Pow (. ..) реализация хорошо написана.

10 особенный для нас, так как у большинства из нас есть десять пальцев. Компьютеры имеют только две цифры, поэтому 2 является для них особенным. :)

...