Чому множення працює швидше ділення

По-перше, це стосується тільки компільованих ЯП в яких цілі і дійсні числа представлені нативними типами даних апаратної платформи. Тобто 8/16/32/64-цілі і 32/64/80-бітові дійсні. Все це ніяким чином не стосується динамічних скриптів, а також мов, в яких числа за замовчуванням з довгою арифметикою або межі значень не вказані в специфікації мови (зазвичай це означає використання довгої арифметики) - у всіх цих випадках обчислення йтимуть в десятки / сотні / тисячі разів повільніше ніж на голому залозі і різниці між множенням і діленням (а також іншими операціями) не буде помітно взагалі.
По-друге, навіть на компільованих мовах з нативними типами даних, іноді зустрічаються додаткові перевірки (на переповнення, наприклад) і особливі правила застосування математичних дій, що впливає на продуктивність набагато сильніше, ніж різниця між розподілом і множенням. Хороший приклад - дивовижний випадок на cython.

По суті процесор вміє працювати тільки з битами
З цілими числами все виглядає давольно просто:
1й біт числа визначає знак числа - 0 для позитивних і 1 для негативних
У нас є операції для управління битами:
інверсія
  • кон'юнкція
  • | диз'юнкція
  • >> зрушення вправо
  • <<сдвиг влево

  • введемо арифметичні операції по порядку:
    1. Додавання, зводиться по суті до складання бітів в стовпчик
    2. Заперечення або зміна знака, -a виражається як
    a + 1
  • Віднімання a - b виражається через a + -b
  • Множення, тут кілька варіантів, залежить від компілятора і його оптимізатора:
    1. Множення на ступеня 2 можна уявити зрушенням вліво: a * 8 приводиться до a <<3 т.к. 8 - это 3я степень 2
    2. Прості випадки на кшталт a * 3 можна замінити на a + a + a
    3. Випадки по складніше a * 11 складати a 11 раз саме з собою не оптимально
      розкладаємо 11 на ступеня 2: 11 = 8 + 2 + 1
      обчислюємо (a <<3) + (a <<1) + a

  • З речовими числами все йде складніше, вони теж представлені у вигляді бітів, але частина бітів відводиться під цілу частину, а частина під мантиссу
    По суті число зберігається в експоненційної формі, де мантиса представляє ступінь 2, на яку потрібно помножити цілу частину
    Операції над числами з ненульовий мантиссой більш затратні за кількістю тактів процесора
    Тут нам знадобляться такі речі як експонента і натуральний логарифм, які можна обчислити у вигляді суми ряду, так само через суми ряду обчислюються багато інших математичні функції
    Маючи експоненту і логарифм можна висловити ступеневу функцію
    Розподіл же можна уявити через множення і ступеня

    Ось така ось вища математика над двійковими числами відбувається "за кадром" наших на вигляд простих програм :)

    sitev.ru - мій блог.

    Зовсім не обов'язково. Ось домігся, що множення працює повільніше, ніж розподіл:

    Ось такі цифри у мене вийшли:

    Test mul
    time = 47
    2.42092e-322
    Test div
    time = 16
    3.73872e-32

    Множення повільно в три рази)

    А вас не бентежить, що при додаванні ще восьми нулів до цифри кількості ітерацій циклу час виконання вашого коду анітрохи не змінюється (замість того щоб зависнути на роки)?
    rextester.com/CGEIT60937

    Ні не бентежить. Я просто намагався спростувати питання "Чому множення працює швидше поділу?". Ніби як вийшло це зробити, копатися глибше - немає часу.

    Чому множення працює швидше ділення

    Програміст і железячнік

    Тому що для поділу потрібно залишковий результат в проміжному етапі розподілу. Тому операція завжди буде послідовною. Щоб додати, відняти і множення можна використовувати схеми прискорення за рахунок розпаралелювання обчислення. З поділом такий номер не пройде, або вийде громіздка схема з дуже довгим інтервалом затримки, що простіше робити це послідовно. Тому в програмуванні переважно уникати операцій ділення, наскільки можливо.
    P.S. Про це можна дізнатися з книг по схемотехніці. Там є розділ для розбору матеріалу з поданням обробка чисел в ЕОМ.

    Схожі статті