Альтернативная реализация SQRT() для STM32 Cortex-M3

Альтернативная реализация функции вычисления квадратного корня числа.

Администратор

Статья будет очень короткой, но надеюсь весьма полезной.

В одном из проектов необходимо было достаточно быстро вычислять некоторую формулу которая в себя включает вычисление квадратного корня 32-х разрядного целого числа. Как показал опыт функция из стандартной библиотеки выполняет вычисления достаточно долго. В итоге пришли к выводу, что необходимо сделать всё самим.

Так и родился этот достаточно короткий и быстрый код:

/*! Функция usr_sqrt(x) − Вычисление квадратного корня.
* \param uint32_t value − число квадратный корень которого нужно вычислять
* \return uint32_t значение квадратного корня
 */
uint32_t usr_sqrt(uint32_t value)
{
    uint32_t d, a;

    __asm {   // поиск номера старшего бита
        CLZ     a, value
        RSB a, a, #0x1F 
    };
    // Нахождение квадратного корня методом Ньютона
    d = 1 << ((a >> 1)+1);    // первое приближение 
    a = (d + ( value >> a )) >> 1;
    d = (a + value / a)>>1;
    a = (d + value / d)>>1;
    d = (a + value / a)>>1;
    a = (d + value / d)>>1;
    return a;
}

Код достаточно хорошо прокомментирован и лишний раз думаю объяснять его не стоит. Но если кратко, то на ассемблере находится номер старшего единичного бита числа, это означает, что:

// 41646465 = 00000010 01111011 01111001 10000001
// номер старшего единичного бита будет 25, необходимо учесть, счёт начинается с 0

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

Буду рад любым комментариям по поводу ускорения данного кода.