Чи 2 ** x швидше обчислити, ніж exp (x)?


12

Пробачте наївність, що буде очевидно в тому, як я задаю це питання, а також у тому, що я його задаю.

Математики зазвичай використовують оскільки це найпростіша / найприємніша база в теорії (за рахунок обчислення). Але комп'ютери, здається, роблять все в двійковому, тож чи швидше на машині обчислити, ніж ?exp2**xMath::exp(x)


7
Про яку кількість ви говорите? Ціле число розміром арбітражу? Плаваюча точка з фіксованим розміром? Довільна точність плаваючої точки?
Жил 'ТАК - перестань бути злим'

@Gilles Це хороший момент. Я не розумів, що різниця важлива.
ізоморфізм

3
Я бачив на деяких кишенькових калькуляторах Casio, що журнал і потужність не-е числа набагато повільніше, ніж ln / exp
phuclv

2
Ви ризикуєте бути притупленими, чи намагалися ви встановити їх обоє і побачити, що швидше? Або ви говорите про швидкість у сенсі складності ? O(f(n))
jmite

1
Мова відповідає за те, щоб вибрати найшвидший спосіб, і він добре зробить його. Тільки у випадку, якщо потрібна максимальна швидкість, і вимірювання показали, що це стосується продуктивності, якщо ви турбуєтесь про подібні речі
vonbrand

Відповіді:


18

Оскільки це CS, а не Stackoverflow, я припускаю, що ви задаєте питання про числовий аналіз та (щоб все було просто) IEEE-754 з плаваючою точкою. У такому випадку відповідь на ваше запитання частково залежить від того, що ви маєте на увазі під "легше", а частково від деталей системи.

У жодному із сучасних процесорів, про які я знаю, немає вбудованої інструкції, яка б виконувала саме те, що ви очікували, або для операції (яку ми далі назвемо , її звичайна назва в С), або ( ). Вони реалізовані за допомогою функцій бібліотеки.2 xexexp2xexp2

Як і у випадку з усіма числовими методами трансцендентальних операцій, слід врахувати кілька особливих випадків:

exp(NaN) = NaN
exp(+Inf) = +Inf
exp(-Inf) = 0

Однак є ще одна річ, яка робить проблему трохи менш складною: корисний домен зовсім невеликий. Для binary32 підтоки, exp(x)якщо або близько того, і переповнення, якщо або близько того. Незвично для трансцендентних операцій, ми також можемо ігнорувати регістр субнормального, так як нічим НЕ відрізняються від , якщо субнормального. Все вищезазначене також стосується, за винятком того, що домен дещо інший.x > 88.7x<104x>88.7exp(x)1.0xexp2

Ваша інтуїція права в тому, що більшість реалізацій обчислює . Однак вартість цього множення на тривіальна порівняно з рештою обчислень . Типовий метод використовує попередньо обчислену таблицю з елементами :1ex=2x/ln2 К1ln2exp2K

exp2(x)=2n×T[j]×P(y)

де - ціла частина , таблиця містить значення для всіх в діапазоні , а - деяке поліноміальне наближення до (кватерний достатній для двійкового32 ) в діапазоні . частина дешева, так як це просто маніпулюючи показник. - таблиця пошуку. Тож , швидше за все, буде дорогою частиною операції.x T 2 j / K j [ 0 , K ) P 2 x [ 0 , 1nxT2j/Kj[0,K)P2x2nTP[0,1K)2nTP

Я повинен зазначити для повноти, що FPU Intel x86 включає в себе інструкцію під назвою f2xm1, яка обчислює для у діапазоні . Однак на сучасному процесорі це досить дорога та непрофільна інструкція, і ви сильно не відмовляєтесь від її використання. Як справедливо зазначає Посібник з оптимізації Intel Розділ 3.8.5:х [ - 1 , 1 ]2x1x[1,1]

Хоча x87 підтримує трансцендентні інструкції, у багатьох випадках реалізація програм трансцендентальної бібліотеки може бути швидшою.

Редагувати: У коментарях було зазначено, що я повинен пояснити деякі нові термінології, які використовуються в IEEE 754-2008. Частина мови змінилася з 1985 і 1987 років, і більшість людей набагато більше знайомі зі старим жаргоном.

Терміни "binary32" та "binary64" - це нові назви для 32-розрядних та 64-бітних двійкових чисел з плаваючою комою, які старий стандарт називав відповідно "одиночний" та "подвійний".

Термін "субнормальне число" замінює попередній термін "деннормальне число" або "денормальне число" .


коли ви говорите "субнормальне" - ви чітко не маєте на увазі "субгаусський"; ти маєш на увазі "гірше [якийсь орієнтир типовості]"?
ізоморфізм

2
@isomorphismes Тут «субнормальне» стосується того, як реалізуються плавки. Дивіться деннормальні номери у Вікіпедії.
Пол Манта

Між іншим, я трохи спростив "типовий метод". Можна реалізувати exp2 () та exp () з точністю ulp, використовуючи лише одне невелике (і досить легко зрозуміле) розширення до методу, представленого тут, але пояснення невеликого простого для розуміння розширення, ймовірно, подвоїть довжину відповідь!
Псевдонім

6

2**x2x<<1 << x


4
насправді. х, можливо, тип з плаваючою комою
phuclv

1
x

Якщо xце не ціле число (скажімо, 20.75), ви б встановили мантісу 2та показник на округлене значення xяк найбільш точну оцінку (точне подання неможливо). Що теж набагато швидше, ніж `pow '.
Деймон

1

Якщо 2**xце функція на цілі числа, то я згоден з відповіддю Стівена, переміщення дешевше. Але я зазвичай бачу це як 2^xі **для вказівки на плаваючу точку. У цьому випадку я б очікував аналогічних показників між **і ^оскільки обидва expта pow(основна операція для **) є обома операціями трансцендентального наближення.


Цікаво, що я не знав, що **вважається синонімом версії з плаваючою комою (і, нерозумно, я забув, що два будуть іншими).
ізоморфізм

1

Оскільки 2 ^ x = e ^ (x * ln 2) та e ^ x = 2 ^ (x * log2 (e)), ви не очікували б великої різниці.

Для x, близького до нуля, зазвичай використовується поліном e ^ x = 1 + x + x ^ 2/2 + x ^ 3/6 ..., добре оптимізований для того, щоб скоротити якомога швидше, зберігаючи невелику помилку округлення . Зрозуміло, що 2 ^ х - це крихітний, крихітний трохи повільніше для обчислення. "x близьке до 0" зазвичай буде значенням x, де sqrt (1/2) <= e ^ x <= sqrt (2). Обмеження діапазону x гарантує, що ступінь полінома не слід вибирати занадто високим.

Для більшого х зазвичай можна обчислити 2 ^ х, якщо додати x = x '+ x' ', де x' - ціле число, а -0,5 <= x '' <= 0,5. 2 ^ x 'буде обчислено, побудувавши число з плаваючою точкою з правильним бітовим малюнком, а 2 ^ x' 'за допомогою методу e ^ x для малого x. Тут 2 ^ х - крихітний трохи швидше. Більше того, якщо x є великим (скажімо x = 100,3), просто множення x на log2 (e) введе неприйнятну помилку округлення (тому що менше дріб дрібних бітів), тому потрібно бути обережнішими.

І, сподіваємось, хороша функція бібліотеки піклується про те, щоб щоразу, коли x <= y, e ^ x <= e ^ y і 2 ^ x <= 2 ^ y, незалежно від помилок округлення. Досягти такої речі може бути складним.


0

Ви повинні зрозуміти, що математика на комп’ютері здійснюється різними способами різним програмним забезпеченням, сподіваємось, що вони знайдуть відповіді. Дивлячись на більшість програмного забезпечення, я думаю, що комп’ютери поводяться як добре - комп’ютери, і я підрахую відповідь довгий шлях навіть на зразок 0 ^ 0. Проблема полягає в тому, що в особливих випадках пов'язано "розпізнавання", яке не відбувається безкоштовно в цифрових комп'ютерах. Це означає, що лише в тих випадках, коли відповідь прискорить ситуацію, "найбільше" відбудеться оптимізація. Але в тих випадках це відбудеться надзвичайно добре. Також зауважте, що для отримання правильної відповіді, можливо, доведеться зробити кілька різних визнань. Це називається рівнем оптимізації швидкості, і це відбулося з максимальною професійною мірою на основі більшості програмного забезпечення під назвою GNU "C". Це пояснюється тим, що тут мінімальні відмінності часу роботи від програмного забезпечення до програмного забезпечення та від машини до машини використовуються там як цифри прийняття якості. В інших перекладачах, як правило, тільки якщо "нульовий прапор" виникає як побічний ефект попередніх обчислень, пришвидшиться розпізнавання. наприклад 0 * x => C0.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.