2011-05-27 2 views
2

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

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

+0

Является ли m целым числом? Всегда ли это положительно? Каково его максимальное значение? Если вы не укажете такие ограничения, то вы не получите оптимального решения. –

+2

Как было сказано в некоторых ответах, 9 + 1 не является специальной базой, если только вы не являетесь человеком, который, по совпадению, оказывается таким количеством пальцев. Но ваш компьютер этого не делает, поэтому избегайте базы 10. Это имеет смысл только при работе с данными, где кто-то действительно будет читать числа, но это интересно только тогда, когда их не более 100, а для таких небольшие количества, производительность на самом деле не имеет значения. – leftaroundabout

+0

Вам нужно интегральное решение или с плавающей точкой? Являются константами времени компиляции 'n' или' m'? – MSalters

ответ

0

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

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

5

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

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

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

+0

Вы действительно хотите написать * недостаток *? –

+0

@space прогностическая клавиатура на моем телефоне сделала это решение спасибо! –

+0

Благодарим за быстрый ответ. pow может сделать для настольных ПК. – GoldenLee

4

Десять не является особым значением на двоичной машине, только два. Используйте pow или exponentiation by squaring.

+0

Да. Ты прав! 10 - это особый номер в нашей повседневной жизни и в классе начальной школы, но не в компьютерном мире. – GoldenLee

2

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

+0

Спасибо. Я согласен с вашим предложением построить таблицу поиска для разумного (не слишком большого) показателя. – GoldenLee

0

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

0

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

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

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

+0

Thye decimal с плавающей точкой - материал IBM; вы найдете его на своих мэйнфреймах. – MSalters

0

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

n = pow(10*n,-m) 

теперь вы должны вычислить (с помощью определения L = log10 (п))

l = -m*(l+1) 
+0

Дорогой Питер, спасибо за внимание. Я не совсем понимаю ваше решение моего вопроса. Я хочу оценить значение x = n * pow (10, -m). Таким образом, дальнейшие предложения будут высоко оценены! – GoldenLee

0

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

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

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

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

  4. Я думаю, это также стоит посмотреть на OpenCL

+0

Дорогой Ули, Спасибо за ваши добрые предложения. Усовершенствованные технологии, такие как параллельная вычислительная техника, Intel/LPP, CUDA и OPenCl, как вы упомянули здесь, будут связаны с улучшением производительности приложений с широким охватом. – GoldenLee

0

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