AVR GCC mnozenie wielkich liczb

Hej mam taki problem z kompilatorem AVR GCC - na moj gust zglupial lub pewnei robie cos zle. jest takie powiedzenie, jesli twierdzisz ze kompilator jest glupi - idz spac. ale nie w tym rzecz. mam wynik pomiaru w postaci liczby 32 bit (wynik z ukladu TCD pomiaru czasu z rozdzielczoscia 7ps(sic!)) i potrzebuje go przemnozyc przez stala 7.629453 nie chce uzywac arytmetyki zmiennoprzecinkowej, zreszta z jakis powodow ona tez nie dziala.

wersja zmiennoprzecinkowa float calc_temp; uint32_t calc_temp1; calc_temp1 = TDC_Read(0); if (calc_temp1 != 0xFFFFFFFF) //overrange detection { calc_temp = (calc_temp1*7.629453); tlcd_write_U32((U32)calc_temp); tlcd_write_string("ps"); } else tlcd_write_string(" OVR ");

no i wynik nie dosc ze jest bez sensu to zawija sie gdzies przy 16 bitach, ale to musze dokaldneij sprawdzic

wersja integer:

uint64_t calc_temp; U32 calc_temp1; calc_temp1 = TDC_Read(0); if (calc_temp1 != 0xFFFFFFFF) //overrange detection { calc_temp = (calc_temp1*7629453UL)/1000000UL; //result in ps tlcd_write_U32((U32)calc_temp); tlcd_write_string("ps"); } else tlcd_write_string(" OVR ");

Wynik wydaje zawijac sie gdzies na 16 bitach lub wczesniej. nie pomaga zadeklarowanie liczb jako 1000000ULL, jedyny efekt uboczny to taki ze objetosc kodu zwieksza sie o 4KB - widac kompilator wlacza biblioteki 64bit?? o robie zle? pewnie znow sie okaze ze gdzies do zmiennej powinienem byl dodac jakas literke...

z innej beczki: czy spotkaliscie sie z bibliotekami w C konwerujacymi np U32 na BCD? napisalem sobie wlasne,ale na pewno nie sa optymalne jesli chodzi o kod, a pewnie istnieja gdzies eleganckie napisane w ASM...

Reply to
Greg(G.Kasprowicz
Loading thread data ...
Reply to
invalid unparseable
Reply to
Greg(G.Kasprowicz

Greg(G.Kasprowicz) napisał(a):

[...]

Musisz pamiętać, że sposób obliczania jest niejako narzucony przez pierwszą operację. Czyli w powyższym mnożeniu liczby 32-bitowej calc_temp1 przez 32-bitową stałą 7629453UL już masz problem - będzie przepełnienie i obcięcie. Potem dzielisz to przez kolejną 32-bitową stałą 1000000UL i nic sensownego z tego działania nie pozostanie.

Powinno zadziałać takie rozwiązanie (sprawdź): uint64_t a, b, c; a = TDC_Read(0); b = (a * 7629453ULL) / 1000000ULL;

Jeżeli a jest 32-bitowe to przed mnożeniem zrzutuj je na 64 bity: b = (uint64_t) a * 76294... I jak poszło? Pamiętaj, że stałe 64-bitowe w AVR wymagają dopisku LL / ULL.

Reply to
Adam Dybkowski
Reply to
Greg(G.Kasprowicz

Greg(G.Kasprowicz) napisał(a):

Obejrzyj w mapie linkera (i ew. listingu po deasemblacji) jakie funkcje zajęły najwięcej. Mnożenie 64-bitowe bez problemu napiszesz na kolanie i zajmie mniej niż kilkaset bajtów. Albo ściągnij gotowe z Sieci.

Reply to
Adam Dybkowski

No i jak chcesz przemnozyc przez 7,629453 to moze szybciej bedzie przemnozyc przez 32768251121 a potem "podzielic" przez 2^32

J.

Reply to
J.F.

Hi hi - a duzo masz czasu ?

Bo jesli na jedno wejscie sumatora podasz liczbe, a na drugie jego wyjscie podzielone przez 4, to po chwili wyjscie narosnie do we*1.33333(3)

przemnozmy to przez 2, otrzymamy 2.666666(6), pozostaje dodac 4*we.

Glowy nie dam czy wynik bedzie zawsze stabilny, no i przydaloby sie dla wiekszej dokladnosci najpierw wejscie "przemnozyc" np *8, a na koniec podzielic/4

Swoja droga byc moze to ma calkiem ladna postac funkcji zminimalizowanej .. tylko czym ja wygenerowac :-)

J.

Reply to
J.F.
Reply to
invalid unparseable

hi hi - jeszce jedno podobne: - nie dodawac, tylko odejmowac polowe. Wynik sie ustali na 0.666666(6) .. czyli najpierw przemnozyc przez 10 [jeden sumator].

Hm, z sumowaniem chyba bedzie, ten z odemowaniem to nie dam glowy :-)

J.

Reply to
J.F.

tez o tym pomyslalem, bedzie chyba szybciej,skoro i tak juz mnoze, to odpadnie dzielenie, bo potem tylko wezme starsza czesc

Reply to
Greg(G.Kasprowicz
Reply to
Greg(G.Kasprowicz
Reply to
Greg(G.Kasprowicz
Reply to
Greg(G.Kasprowicz

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.