|
Виж темите без отговор | Виж активните теми
Дата и час: Вто Юли 28, 2026 1:36 am
| Автор |
Съобщение |
|
Vilo
Ранг: Минаващ
Регистриран на: Пон Апр 03, 2006 9:00 am Мнения: 39
|
 Не ме п&am
Не е чак толкова сложно колкото ви се струва. Ето пример, само че за sin i cos. Така смятат 99% от калкулаторите.
Използва само shift, add и sub при това само с int; Ако някой удари едно MATH рамо за подобен CORDIC алгоритъм за arc sin, ще почерпя.
#define AG_CONST 0.6072529350
#define FIXED(X) ((long int)((X) * 65536.0))
#define FLOAT(X) ((X) / 65536.0)
#define DEG2RAD(X) 0.017453 * (X)
typedef long int fixed; /* 16.16 fixed-point */
static const fixed Angles[]={
FIXED(45.0), FIXED(26.565), FIXED(14.0362),
FIXED(7.12502), FIXED(3.57633), FIXED(1.78991),
FIXED(0.895174),FIXED(0.447614),FIXED(0.223811),
FIXED(0.111906),FIXED(0.055953),FIXED(0.027977) };
int main(void)
{ fixed X, Y, TargetAngle, CurrAngle;
unsigned Step;
X=FIXED(AG_CONST); /* AG_CONST * cos(0) */
Y=0; /* AG_CONST * sin(0) */
TargetAngle=FIXED(28.027);
CurrAngle=0;
for(Step=0; Step < 12; Step++)
{ fixed NewX;
if(TargetAngle > CurrAngle)
{ NewX=X - (Y >> Step);
Y=(X >> Step) + Y;
X=NewX;
CurrAngle += Angles[Step]; }
else
{ NewX=X + (Y >> Step);
Y=-(X >> Step) + Y;
X=NewX;
CurrAngle -= Angles[Step]; }}
printf("CORDIC: sin(%7.5f)=%7.5f, cos(%7.5f)=%7.5f\n",
FLOAT(TargetAngle), FLOAT(Y),
FLOAT(TargetAngle), FLOAT(X));
printf(" FP: sin(%7.5f)=%7.5f, cos(%7.5f)=%7.5f\n",
FLOAT(TargetAngle), sin(DEG2RAD(FLOAT(TargetAngle))),
FLOAT(TargetAngle), cos(DEG2RAD(FLOAT(TargetAngle))));
return(0); }
|
| Чет Апр 05, 2007 9:15 am |
|
 |
|
HCL
Ранг: Форумен бог
Регистриран на: Вто Дек 14, 2004 1:31 pm Мнения: 3849
|
@evc ако ми дадеш пример за LUT с вьзможност за тьрсене чрез offset, при нелинейна функция и изискване за константно отклонение, ще те черпя виртуална бира. Като се замисля, нека са две  Според мен е невьзможно, но може и да греша.
За другото сьм сьгласен, прав си. Подведох се по
@Valio с това задание ти е мьтна нещо водата. Няма как да използваш int, при положение че ти трябва точност от 0.05 градуса, ще се наложи да прибегнеш до 32bit-ова променлива. Освен разбира се, akо тази точност не е в целия диапазон +/- pi/2, което ти услеснява страшно много заданието.
|
| Чет Апр 05, 2007 9:17 am |
|
 |
|
bobyk
Ранг: Ориентиран
Регистриран на: Пон Яну 09, 2006 11:32 am Мнения: 276 Местоположение: Kozloduy
|
Добре де, на АСМ ли искаш да го пишеш. Че то С си има библиотчка, не можеш ли да заимстваш малко код, на АВР се компилира в ~640words, koeto все пак е повече от 1к флаш
Не бях видял последните няколко поста 
|
| Чет Апр 05, 2007 9:39 am |
|
 |
|
setoy
Ранг: Почетен член
Регистриран на: Пет Фев 17, 2006 9:17 am Мнения: 765 Местоположение: Стара Загора
|
|
| Чет Апр 05, 2007 9:58 am |
|
 |
|
zaphod
Ранг: Форумен бог
Регистриран на: Нед Юли 24, 2005 10:28 am Мнения: 2658
|
пич, не знам какви глупости ви учат в даскалото, обаче аз си смятам синус на асемблер без проблем. аркус синус не ми се е налагало, ама ако се наложи и него ще направя без да ми мигне окото.
|
| Пет Апр 06, 2007 6:49 pm |
|
 |
|
Vilo
Ранг: Минаващ
Регистриран на: Пон Апр 03, 2006 9:00 am Мнения: 39
|
 PICH?!
Sorry maina, ama pich, ne e podhodiashto obrashtenie (nishto lichno), struva mi se tuk. Niakoi mladeji/devoiki sa daleko ot prilojnata matematika - spor niama (kakto i az btw), no chovek se uch dokato e jiv.
Sled malko iteracii na baza na post-natia veche ot men CORDIC algoritam, smeia da izloja cod za izchislenie na arcus sinus doblijavasht se do zadanieto:
#define MAXBITS 20
const float atanTable[MAXBITS] =
{
0.785398185253,
0.463647603989,
0.244978666306,
0.124354995787,
0.062418811023,
0.031239833683,
0.015623728745,
0.007812341210,
0.003906230209,
0.001953122555,
0.000976562209,
0.000488281221,
0.000244140625,
0.000122070313,
0.000061035156,
0.000030517578,
0.000015258789,
0.000007629395,
0.000003814697,
0.000001907349
};
#define invGain1 0.607253015041
float asinCordic(float a)
{
/* |a| < 0.98 */
float x, y, z;
x = invGain1;
y = 0;
z = 0;
int neg = 1;
if (a < 0) {
a = -a;
neg = 0;
}
cordit1(&x, &y, &z, a);
if (neg) z = -z;
return z;
}
void cordit1(float* x0, float* y0, float* z0, float vecmode)
{
float t;
float x, y, z;
int i;
t = 1;
x = *x0; y = *y0; z = *z0;
for (i = 0; i < MAXBITS; ++i) {
float x1;
if (vecmode >= 0 && y < vecmode || vecmode<0 && z >= 0) {
x1 = x - y*t;
y = y + x*t;
z = z - atanTable[i];
}
else {
x1 = x + y*t;
y = y - x*t;
z = z + atanTable[i];
}
x = x1;
t /= 2;
}
*x0 = x;
*y0 = y;
*z0 = z;
}
E, pochti copy-paste, a s malko "igrachka" shte go sveda do nujdite mi. Vsichki izkazali mnenie za nevazmojnostta na reshenieto - da chetat poveche, na ostanalite - blagodaria za alternativite.
|
| Съб Апр 07, 2007 4:47 am |
|
 |
|
Taner
Ранг: Новодошъл
Регистриран на: Пет Юли 08, 2005 3:46 pm Мнения: 112 Местоположение: Пловдив
|
Хора, мислете по простичко де, be cool friends.
Веднъж като влезна в този форум и прочета за някоя тема, после цяла седмица не мога да напиша и ред свестен код.
В този форум човек получава комплекс за малоценност, обяснявайте и правете нещата по просто, или то си е в природата на човека сам да си усложнява живота и да си създава проблеми, които после да се опитва отново да решава, като отново си създава нови проблеми и т.н., един безкраен и глупав цикъл. Или някой се опитва да избива комплекси тука.
Работете, работата краси човека 
|
| Съб Апр 07, 2007 1:23 pm |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30686 Местоположение: София
|
То хубаво просто но какво конкретно предлагаш?
|
| Съб Апр 07, 2007 8:46 pm |
|
 |
|
Vilo
Ранг: Минаващ
Регистриран на: Пон Апр 03, 2006 9:00 am Мнения: 39
|
 pochti reshenie....
typedef long fixed; // 16.16 fixed-point
#define FIXED(X) ((long)((X) * 65536.0))
#define AG_CONST (FIXED(0.607252935008882))
const fixed Table[]=
{
FIXED(45.000000000),
FIXED(26.565051177),
FIXED(14.036243468),
FIXED(7.1250163489),
FIXED(3.5763343750),
FIXED(1.7899106082),
FIXED(0.8951737102),
FIXED(0.4476141709),
FIXED(0.2238105004),
FIXED(0.1119056771),
FIXED(0.0559528919),
FIXED(0.0279764526),
FIXED(0.0139882271),
FIXED(0.0069941136),
FIXED(0.0034970569),
FIXED(0.0017485284)
};
ldiv_t asin_cordic (long a) // scaled * 65536
{
fixed x;
fixed y = 0;
fixed z = 0;
fixed x1;
ldiv_t res;
unsigned char i;
x = AG_CONST;
for(i = 0; i < 16; i++)
{
if (((a >= 0) && (y < a)) || ((a < 0) && (z >= 0)))
{
x1 = x - (y >> i);
y = y + (x >> i);
z = z - Table[i];
}
else
{
x1 = x + (y >> i);
y = y - (x >> i);
z = z + Table[i];
}
x = x1;
}
res = ldiv(-z, 65536);
return(res);
}
Greshkata v ugala e sled 3-tia znak sled zapetaiata, predostatuchno za povecheto nujdi. I vse oshte neznam zashto greshi poveche v ugli m/u 37.3 i 43.3 deg. Smetkata e samo za I kvadrant, proverkata za znaka pravia vuv vikashtata funkcia.
|
| Нед Апр 08, 2007 4:01 pm |
|
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 3 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|