Aktyw Forum

Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.

Sprawdź punkty Zarejestruj się

SDCC Proste mnożenie i dziwny błąd wyniku na jednym bicie ..

silver777
-
-
Posty:3
Rejestracja:9 sty 2005, o 13:11
Lokalizacja:śląsk
SDCC Proste mnożenie i dziwny błąd wyniku na jednym bicie ..

Postautor: silver777 » 9 sty 2005, o 13:35

Witam!
Ostatnio spotkałem się z dosyć dziwnym zjawiskiem w SDCC, mianowicie :

unsigned char a=0xff;
unsigned char b=0xff;
unsigned char c=0xff;
long wynik;

wynik=a*65536+b*256+c;

daje w wyniku: 0x00FEFFFF !!!
Tak jest FE , 16-sty bit jest zawsze zerowy niezależnie od wartości a,b,c :(
Reszta bitów obliczana jest prawidłowo.

Wydaje mi się, że jest to błąd kompilatora.
Obserwując kod w assemblerze zauważyłem, że przy "okrągłych" wartościach stosuje on przesunięcia w lewo, a już przy 65535 mnożenie long. Niestety nie działa to zbyt dobrze :(
Może jest jakiś sposób by zawsze stosował mnożenie ?!

Jeśli ktoś już się z czymś takim spotkał i potrafi to wytłumaczyć lub rozwiązać to bedę wdzięczny za wszelką pomoc :)

Procesor: ADuC834, SDCC: 2.4.0, zmienne w obszrze DATA.

Pozdrawiam - silver777

tdolata
-
-
Posty:18
Rejestracja:6 gru 2004, o 10:56
Lokalizacja:Poznań

Postautor: tdolata » 10 sty 2005, o 08:55

Sprawdziłem na gcc i efekt dokładnie ten sam. Sądzę, że jest to spowodowane tym, że kompilator domyślnie rozszerza typ stałych do najbliższej pasującej. Przy 65536 nie ma problemu (najbliższy to long), ale problemem jest 256 (tylko int). Do procedury realizującej mnożenie, na dwóch najstarszych bajtach, przekazywane są jakieś dziwne argumenty.

Spróbuj:
wynik=a*65536L+b*256L+c;

to powinno pomóc.

silver777
-
-
Posty:3
Rejestracja:9 sty 2005, o 13:11
Lokalizacja:śląsk

Postautor: silver777 » 10 sty 2005, o 11:25

Rzeczywiście pomogło :))

Dziękuje bardzo za pomoc !

Dobrze wiedzieć, na jakie rzeczy trzeba uważać w tych kompilatorach, SDCC dopiero poznaję, wcześniej pisałem w Keilu.

Czy jest gdzieś może opis największych znanych "bug'ów", bo po włączeniu :
http://sourceforge.net/tracker/?group_i ... tid=100599
-można dostać zawrotu głowy :)

Jeszcze raz dziękuję i pozdrawiam !

Arrek
-
-
Posty:117
Rejestracja:18 wrz 2003, o 20:41
Lokalizacja:wawa

Postautor: Arrek » 11 sty 2005, o 12:26

silver - zobacz tez cos takiego (ciekawi mnie czy pomoze). mniej eleganckie niz propozycja tdolaty, ale powinno tez pojsc

wynik = ((long)a)*65536 + b*256 + c;

zrzutowanie zmiennych na long sprawi, ze stale tez beda traktowane jako longi. Dodawanie do longa intow i charow nic nie zmieni - otrzymamy long. To tak jakby a, b i c byly typu long a nie unsigned char.

silver777
-
-
Posty:3
Rejestracja:9 sty 2005, o 13:11
Lokalizacja:śląsk

Postautor: silver777 » 12 sty 2005, o 09:30

wynik = ((long)a)*65536 + b*256 + c;

dziala tak samo jak a*65536 + b*256 + c; (czyli zle) :(

Tak jak napisal tdolata problemem jest cze

[ Dodano: 12-01-2005, 08:41 ]
(.. ciag dalszy, przepadkiem mi sie wyslalo w polowi, przepraszam)

Tak jak napisal tdolata problemem jest czesc mnozona *256, gdyz kompilator z niej robi integer, wyrazenie:

wynik=a*65536+((long)b)*256+c;

dziala dopiero poprawnie, bo do srodkowej czesci sumy zaczyna uzywac procedur od longow :)

Nie wieadomo tylko czy przy pewnych wartosciach to c, nie bedzie w jakis sposob przeszkadzac, na wszelki wypadek lepiej chyba napisac:

wynik=a*65536+((long)b)*256+(long)c;

Pozdrawiam i dziekuje za pomoc !

Arrek
-
-
Posty:117
Rejestracja:18 wrz 2003, o 20:41
Lokalizacja:wawa

Postautor: Arrek » 12 sty 2005, o 13:08

Rzeczywiscie, nie mialem racji. W sposobie z rzutowaniem trzebaby w sumie dla bezpieczenstwa rzutowac wszystko, a to nie wyglada ladnie w kodzie.

Wróć do „8051”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 3 gości