RTV forum PL | NewsGroups PL

Optymalne przydzielanie rozmiaru zmiennych do mnożenia w C dla AVR ATmega 128

Mnożenie dużych liczb w AVR C

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Optymalne przydzielanie rozmiaru zmiennych do mnożenia w C dla AVR ATmega 128

Michał
Guest

Wed Apr 18, 2007 3:06 pm   



Witam wszystkich
Mam takie pytanie do praktyków piszących w C dla rodziny AVR. Jak optymalnie
przydzielać rozmiar zmiennej w przypadku mnożeń liczb.
Podam na przykładzie

a=250;
b=250;
c=250
d=?

d=a*b*c;

No własnie, ile bitów przydzielić konkretnym zmiennym? D oczywiście musi być
32 bitowa, by pomieścić wynik, ale czy A i B i C mogą być 8 bitowe? Chodzi
mi o
sam proces obliczeń.

Test w builderze oblicza prawidłowo to równanie, ale w AVR jak zrobiłem
podobny przykład niestety dostałem śmieci.
Ten przykład poniżej wyświetla mi 63236 zamiast spodziewanych 48800.

uint8_t x1,x2,x3,x4;
uint16_t y1,y2,y3;

x1=250;
x2=250;
x3=128;
x4=100;

y1=((x1*x2)/x3)*x4;
wyswietl(128,30,y1);

Czy np. lewa zmienna działania musi pomieścić wynik działania? Np dla x1*x2,
x1 musi być 16 bitowy? Jest jakaś regóła jakiej trzeba się trzymać?
Czyli jak to robić optymalnie, bo zapewne mnożenie dwóch cyfr 16 bitowych
jest znacznie szybsza od 32 bitowych, nie wspominając już o 8 bitach.

Kompilator to WinAVR ściagany może miesiac temu, wiec aktualny. Procesor to
ATMEGA 128. Pamięci SRAM pod dostatkiem.

Pozdrawiam

J.F.
Guest

Wed Apr 18, 2007 6:16 pm   



On Wed, 18 Apr 2007 16:06:08 +0200, Michał wrote:
Quote:
Ten przykład poniżej wyświetla mi 63236 zamiast spodziewanych 48800.
uint8_t x1,x2,x3,x4;
uint16_t y1,y2,y3;

x1=250;
x2=250;
x3=128;
x4=100;

y1=((x1*x2)/x3)*x4;

Najwyrazniej mnozy ci dwa pierwsze ze znakiem.
250*250=62500= -3036

Quote:
Czy np. lewa zmienna działania musi pomieścić wynik działania?

To niewatpliwie, ale ogolnie w C to malo.
Jeszcze co najmniej jeden ze skladnikow powinien miec taki typ.

Przy czym AVR GCC sporo obliczen rozszerza samodzielnie do int -
czesto zupelnie niepotrzebnie.

Quote:
Np dla x1*x2, x1 musi być 16 bitowy?

sprobuj uint16, ale moze byc za malo - tu mu wyraznie brakuje bitu
znaku. bezpieczniej bedzie
y1=(((long)x1*x2)/x3)*x4;

Quote:
Kompilator to WinAVR ściagany może miesiac temu, wiec aktualny. Procesor to
ATMEGA 128. Pamięci SRAM pod dostatkiem.

Dla takich obliczen ... zmienny przecinek :-(


J.

Rogher
Guest

Thu Apr 19, 2007 5:29 am   



Michał pisze:
Quote:
Witam wszystkich
Mam takie pytanie do praktyków piszących w C dla rodziny AVR. Jak
optymalnie
przydzielać rozmiar zmiennej w przypadku mnożeń liczb.
Podam na przykładzie

a=250;
b=250;
c=250
d=?

d=a*b*c;

(cut)


Nie mam praktyki w AVR ale niezależnie od uC zmienne a, b, c zrób
unsigned char natomiast d oczywiście 32-bit (ew. 24 jeżeli masz taką opcję).
Następnie często pomaga rozbicie działania na mniejsze i konwersja typu
(wskazanie kompilatorowi na jakich typach zmiennych jest to działanie).

d = (u32)a * b //tu kompilator być może wykorzysta funkcję u32*u8
d *= c // tu też

albo:

d = a;
d *= b;
d *= c;

Pokombinuj z takimi możliwościami, podejrzyj assemblera i zobacz co
bardziej optymalne. Jeżeli jest to mnożenie liczb bez znaków to deklaruj
też te liczby jako unsigned, bo będzie jak mówił ktoś wcześniej -
kompilator może przyjąć że 250 = -6

pozdrawiam

Rogher

elektroda NewsGroups Forum Index - Elektronika Polska - Optymalne przydzielanie rozmiaru zmiennych do mnożenia w C dla AVR ATmega 128

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map