0x7F Традиционный вопрос. Я перенес с Фортрана на Си одну классическую процедуру.
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Bill 04 сентября 2004 г. 14:52

Для проверки странслировал ее компиляторами IAR для MSP430 и AVR mega. Получилось, что для MSP размер программы оказался в 1.5 раза больше, чем для AVR. Возможно у меня компилятор для MSP старый (2.20A). Кто пользуется более новой версии странслируйте программу, pls. Для сравнения версия компилятора для AVR 2.28.
Оптимизация была сделана по скорости, double - 32 разряда.


#include

//static
double sign (double a, double b)
{
a = fabs(a);
return (b >= 0)? a : -a;
}

//static
double fmax (double a, double b)
{
if (a >= b)
return a;
return b;
}

double zeroin(double (*F)(double), double B, double C, double RE, double AE, char *iflag)
{
char flag;
int count, IC;
double A, ACBS, ACMB, CMB, FA, FB, FC, FX, P, Q, TOL, RW;
double ER;

ER = 4. * 1.19E-07; // R1MACH (4);
RW = fmax(RE,ER);
IC = 0;
ACBS = fabs(B-C);
A = C;
FA = F(A);
FB = F(B);
FC = FA;
count = 2;
FX = fmax(fabs(FB),fabs(FC));
for(;;)
{
if (fabs(FC) < fabs(FB)) // PERFORM INTERCHANGE
{
A = B;
FA = FB;
B = C;
FB = FC;
C = A;
FC = FA;
}
CMB = 0.5*(C - B);
ACMB = fabs(CMB);
TOL = RW*fabs(B) + AE;
if (ACMB <= TOL) // TEST STOPPING CRITERION
{
if (FB*FC > 0.)
{
flag = 4;
break;
}
if (fabs(FB) > FX)
{
flag = 3;
break;
}
flag = 1;
break;
}
//
// CALCULATE NEW ITERATE IMPLICITLY AS B+P/Q
// WHERE WE ARRANGE P >= 0. THE IMPLICIT FORM IS USED TO PREVENT OVERFLOW.
//
P = (B - A)*FB;
Q = FA - FB;
if (P < 0.)
{
P = -P;
Q = -Q;
}
//
// UPDATE A AND CHECK FOR SATISFACTORY REDUCTION IN THE SIZE OF OUR BOUNDING INTERVAL.
//
A = B;
FA = FB;
if (++IC >= 4)
{
if (8.*ACMB >= ACBS) goto l6;
IC = 0;
ACBS = ACMB;
}
//
// TEST FOR TOO SMALL A CHANGE
//
if (P <= fabs(Q)*TOL)
B += (CMB < 0)? -TOL : TOL; // INCREMENT BY TOLERANCE
// ROOT OUGHT TO BE BETWEEN B AND (C+B)/2.
else if (P < CMB*Q)
B += P/Q; // INTERPOLATE
else
l6: B = 0.5*(C+B); // BISECT
//
// HAVE COMPLETED COMPUTATION FOR NEW ITERATE B
//
FB = F(B);
if (FB == 0.)
{
flag = 2;
break;
}
if (++count > 500)
{
flag = 5;
break;
}
//
// DECIDE WHETHER NEXT STEP IS INTERPOLATION OR EXTRAPOLATION
//
if (sign(1.0,FB) != sign(1.0,FC))
continue;
C = A;
FC = FA;
}
//
// FINISHED.
//
*iflag = flag;
return B;
}


Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru