Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Микроконтроллеры и их применение»

Прочитал про интересные ИМХО арифметические грабельки(+)

Отправлено Quasy 08 мая 2008 г. 11:02



Иногда приходится округЛЯДЬ значения. Особенно нам, сирым и
убогим. Для скорости например. Округлять мы умеем, и в конфе
есть прфессионалы по округленной арифметике. Но тут есть
грабельки. Подлые. Например, пусть для управления какой-то байдой
нужно решить систему уравнений (ниже приведен код программы)

38.6x + 4.2y = 240.0
21.6x + 32.6y = 480.0
Решаем ПРИМЕР 1 - C дробной частью....
X1 = 4.97414 это "x"
X2 = 11.42818 это "y"
....................
Теперь округлим - cм. ПРИМЕР 1 - С округленными....
39.0x + 4.0y = 240.0
22.0x + 33.0y = 480.0
X1 = 5.00417 это "х"
X2 = 11.20934 это "у"
Как видим - ошибка от округления небольшая, жить можно.
......................
А вот почти такой же ПРИМЕР2:
11.2x + 13.2y = 240.0
21.6x + 27.6y = 480.0
Решаем - вот результат:
X1 = 12.00000 это "х"
X2 = 8.00000 это "y"
.....................
ОКРУГЛИЛИ ЗНАЧЕНИЯ ДЛЯ ПРИМЕРА 2:
11.0x + 13.0y = 240.0
22.0x + 28.0y = 480.0
Решаем - вот результат:
X1 = 21.81818 это "х"
X2 = 0.00000 это "y"
Здорово отличаются от неокругленного примера2, правда?
///////////////////////////////////////////////////////
Вот тут ниже все эти примеры. Раскомментируйте нужные входные данные и получите результат.
///////////////////////////////////////////////////////
///////// ПРИМЕР 1 - C дробной частью....
#if 1
#define MAX_SYS (2)
float Aa[ MAX_SYS ][ MAX_SYS ] =
{
{ 38.6, 4.2 },
{ 21.6, 32.6 },
};
float Bb[ MAX_SYS ] = { 240.0, 480.0 };
float Xx[ MAX_SYS ];
#endif
///////// ПРИМЕР 1 - С округленными....
#if 0
#define MAX_SYS (2)
float Aa[ MAX_SYS ][ MAX_SYS ] =
{
{ 39.0, 4.0 },
{ 22.0, 33.0 },
};
float Bb[ MAX_SYS ] = { 240.0, 480.0 };
float Xx[ MAX_SYS ];
#endif
//////////////////////////

///////// ПРИМЕР 2 - C дробной частью....
#if 0
#define MAX_SYS (2)
float Aa[ MAX_SYS ][ MAX_SYS ] =
{
{ 11.2, 13.2 },
{ 21.6, 27.6 },
};
float Bb[ MAX_SYS ] = { 240.0, 480.0 };
float Xx[ MAX_SYS ];
#endif
///////// ПРИМЕР 2 - С округленными....
#if 0
#define MAX_SYS (2)
float Aa[ MAX_SYS ][ MAX_SYS ] =
{
{ 11.0, 13.0 },
{ 22.0, 28.0 },
};
float Bb[ MAX_SYS ] = { 240.0, 480.0 };
float Xx[ MAX_SYS ];
#endif
//////////////////////////
void Solution_Sys( void )
{
char i,j,k;
float tmp, Hh;
for( i = 0; i < (MAX_SYS-1); i++ )
{
for( j = i+1; j < MAX_SYS; j++ )
{
tmp = Aa[ i ][ i ];
if( tmp == 0.00 ) tmp = 0.0001;
Aa[ j ][ i ] = -Aa[ j ][ i ] / tmp;
for( k = i+1; k < MAX_SYS; k++ )
{
Aa[ j ][ k ] += ( Aa[ j ][ i ] * Aa[ i ][ k ]);
}//for k
Bb[ j ] += (Aa[ j ][ i ] * Bb[ i ]);
}//for j
}//for i
tmp = Aa[ MAX_SYS-1 ][ MAX_SYS-1 ];
if( tmp == 0.00 ) tmp = 0.0001;
Xx[ MAX_SYS-1 ] = Bb[ MAX_SYS-1 ] / tmp;

for( i = MAX_SYS-2; i < 200; i-- )
{
Hh = Bb[ i ];
for( j = i+1; j < MAX_SYS; j++ )
{
Hh -= (Xx[ j ] * Aa[ i ][ j ]);
}//for j
tmp = Aa[ i ][ i ];
if( tmp == 0.00 ) tmp = 0.001;
Xx[ i ] = Hh / tmp;
}//for i
/////////
for( i = 0; i < (MAX_SYS); i++ )
{
printf( "X%d = %1.5f\n", i + 1, Xx[ i ] );
}//for i

}//void
//////////////////////////
void main( void )
{
Solution_Sys();
}//main
//////////////////////////


Составить ответ | Вернуться на конференцию

Ответы


Отправка ответа
Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 

если вы незарегистрированный на форуме пользователь, то
для успешного добавления сообщения заполните поле, как указано ниже:
скольким Омам равен эквивалент двух резисторов по 10 Ом, соединённых параллельно?:

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru