ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
21 ноября
1341984
BlackMorda, мудак (19.08.2023 09:47, просмотров: 3673)
Восстановил функцию вычисления арктангенса без умножения и деления из ассемблерного текста. Не понятно формирование таблицы. Может кто узнает алгоритм? 

Для повышения точности работа с углами идет с масштабированием 1 градус равен 32 единицам.

Все решения что нашел в Интернете предлагают или разложение в ряд или аппроксимацию.

// у автора старшее значение делится ровно на 32, что соответствует GRAD_SCALE

// далее логично было бы предположить, что идет уменьшение значения в два раза на каждый шаг.

// но первых 4 значения выбиваются из ряда и последние значение равно 0

// если сделать равномерный шаг то последнее значение будет 0.7, что по правилам округления даст 1.

const unsigned int table_arctan_32[12] = {0x5A0, 0x352, 0x1C1, 0xE4, 0x72, 0x39, 0x1C, 0xE, 7, 3, 1, 0};

/*

tabl_arctan

DCD 0x5A0 ;        45 * GRAD_SCALE

DCD 0x352 ;        26.56 // 1.69

DCD 0x1C1;        14.03 // 1.89

DCD 0xE4 ;          7.125 // 1.96

DCD 0x72 ;           3.56 // 2

DCD 0x39 ;          1.78 // 2

DCD 0x1C ;           0.875 // 2

DCD 0xE ;            0.4375 // 2

DCD 7 ;               0.21875

DCD 3 ;              0.09375

DCD 1 ;               0.03125

DCD 0 ;              0

*/

int quasar_arctan(int xx, int yy)

{

int result;

int x = xx;

int y = yy;

// вычисляем квадрант и переставляем

if (y<0)

{

x = -x;

y = -y;

result = (180 * GRAD_SCALE);

}

else

{

result = 0;

}

if (x<0)

{

x = -x;

int tmp = x;

x=y; // R1

y=tmp; // R3

result += (90 * GRAD_SCALE);

}

int R2 = y; // меньшее

int R4 = x; // большее

// цикл вычисления

for (int i=0; i<12; i++)

{

if (y >= 0)

{

result += table_arctan_32[i];

R2 -= x >> i;

R4 += y >> i;

}

else

{

result -= table_arctan_32[i];

R2 += x >> i;

R4 -= y >> i;

}

x = R4;

y = R2;

}

return result;

}
int quasar_arctan(int xx, int yy)

{

int result;

int x = xx;

int y = yy;

// вычисляем квадрант и переставляем

if (y<0)

{

x = -x;

y = -y;

result = (180 * GRAD_SCALE);

}

else

{

result = 0;

}

if (x<0)

{

x = -x;

int tmp = x;

x=y; // R1

y=tmp; // R3

result += (90 * GRAD_SCALE);

}

int R2 = y; // меньшее

int R4 = x; // большее

// цикл вычисления

for (int i=0; i<12; i++)

{

if (y >= 0)

{

result += table_arctan_32[i];

R2 -= x >> i;

R4 += y >> i;

}

else

{

result -= table_arctan_32[i];

R2 += x >> i;

R4 -= y >> i;

}

x = R4;

y = R2;

}

return result;

}