Vit (03.02.2016 02:07 - 04:49, просмотров: 3891)
Посмотрел на листинг и заплакал:) Нужен асмовый 64-бит быстрый:) сдвиг влево на 2. Или вариант быстрого и/или разбивающегося на короткие части квадратного корня для fixed-point. Исходные данные беззнаковые 16.16. Результат (после денормализации) достаточно иметь тоже 16.16.
Исходный вариант для 2.30 где-то выдрал. Вроде похож на классику.
typedef long TFract; /* 2 integer bits, 30 fractional bits */
static inline TFract
FFracSqrt(TFract x)
{
register unsigned long root, remHi, remLo, testDiv, count;
root = 0; /* Clear root */
remHi = 0; /* Clear high part of partial remainder */
remLo = x; /* Get argument into low part of partial remainder */
count = 30; /* Load loop counter */
do {
remHi = (remHi<<2) | (remLo>>30); remLo <<= 2; /* get 2 bits of arg */
root <<= 1; /* Get ready for the next bit in the root */
testDiv = (root << 1) + 1; /* Test radical */
if (remHi >= testDiv) {
remHi -= testDiv;
root++;
}
} while (count-- != 0);
return(root);
}
Пробовал запихивать remHi, remLo в union с unsigned long long - не помогло:)
Корячусь в EW430-6301. Для исходных 16.16 вроде как достаточно меньше проходов сделать, но сдвиг остается.
Нарыл родную IQMATHLIB, но она идет либой без сорцов, ну и хочет DLIB (модуль _atoIQN, выгрызть его не знаю как - может распаковщик и существует), а у меня CLIB и не помню уж почему, но с DLIB что-то другое не срослось.