[#1] OxyPatcher i AmigaE
używanie funkcji matematycznych przy włączonym oxypatcher jest prawie niemożliwe. Powoduje niemalże zamrożenie systemu, na szczęście możliwe jest wyłączenie testowanego programu.
Wkurza mnie wyłączanie za każdym razem oxypachtera gdy chcę się pobawić z AmigaE. U Was też tak jest?
(CPU 040 na BPPC)

[#2] Re: OxyPatcher i AmigaE

@Prince, post #1

Możliwe że jakaś biblioteka matematyczna się buntuje (ale mam chyba(!) standard). Póki co, Oxy leży.

[#3] Re: OxyPatcher i AmigaE

@Prince, post #1

Oryginalne AmigaE zawsze było kulawe pod względem obsługi liczb zmiennoprzecinkowych.
Spróbuj może jakiejś alternatywnej wersji np. CreativE
[#4] Re: OxyPatcher i AmigaE

@shg, post #3

Ostatnio zaczął mi nawet wykonywać odejmowanie przed dzieleniem! Gdybym nie widział na własnym monitorze, to bym nie uwierzył.

Prześpię się z "CreativEm" i zobaczę jak nam będzie ;)

Może ktoś dokładnie wyjaśnić zasadę działania wykrzyknika w składni AmgaE? Konwertuje on liczby zmiennoprzecinkowe na stałoprzecinkowe i na odwrót. Ale może ktoś opisze pełną zasadę. (Wiem że RTFM, ale nie znalazłem w ojczystym języku)

[#5] Re: OxyPatcher i AmigaE

@Prince, post #4

AmigaE wykonuje odejmowanie przed dzieleniem/mnożeniem, bo nie ma priorytetów operacji i wszystko robi jak leci, od lewej do prawej, a nie zgodnie z zasadami.
np. w AmigaE 4-8/4 = (4-8)/4 = -1 :D

Wykrzyknik.
Zapisany przed wyrażeniem:
c:=!a+b; b:=!c+1.0; d:=!a+b*d
Oznacza, że operacja będzie wykonywana jako zmiennoprzecinkowa i tak też potraktowane zostaną zmienne. W ostatnim przykładzie też nie jest brana pod uwagę kolejność wykonywania, więc najpierw będzie dodawanie, a potem mnożenie
Istnieje jeszcze taki zapis: a:=!b, dla kompilatora nie ma on kompletnie żadnego znaczenia, oznacza tylko, że b jest zmiennoprzecinkowe, ale to i tak bez różnicy, bo wszystko jest traktowane jako LONG, w sumie to tak tylko dla użytkownika, żeby wiedział, że to na zmiennym przecinku jest liczone.
Podobnie w zapisie: IF !a>b; wykrzyknik oznacza, że porównywane będą liczby zmiennoprzecinkowe.

zapisany po zmiennej, albo wyrażeniu w nawiasie (dokładnie to chodzi o 'semantic value' ostatniego tokenu na stosie parsera ;) ):
1) a:=b!
2) c:=(a+b)!
3) c:=a+b!
dokonuje konwersji z typu całkowitego na zmiennoprzecinkowy
w pierwszym przykładzie całkowita wartość b zostanie zamieniona na zmiennoprzecinkową i przypisana do a
W przykładzie drugim wyrażenie a+b zostanie obliczone jako CAŁKOWITE i dopiero wynik zostanie zamieniony na postać zmiennoprzecinkową i przypisany do c.
Ostatni przykład jest błędny - wartość b zostanie zamieniona na postać zmiennoprzecinkową, następnie zostanie wykonane CAŁKOWITE dodawanie a do zmiennoprzecinkowej postaci b, śmieci zostaną zapisane do c. w tym wypadku kompilator chyba nawet nie zgłosi błędu, bo z ponktu widzenia kompilatora zapis jest całkowicie poprawny i oznacza bezpośrednie operowanie na zapisie zmiennoprzecinkowym (takie sztuczki mogą się czasem przydać, np do szybkiego mnożenia liczb zmiennoprzecinkowych przez potęgi dwójki (również ujemne, czyli dzielenie przez 2^x)- wystarczy tylko odpowiednio operować wykładnikiem liczby zmiennoprzecinkowej)
Wykrzyknik umieszczony przed i po zmiennej/wyrażeniu w () (chodzi o to samo, co powyżej)
1) c:=!b!
2) c:=!(a+b)!
3) c:=!(!a+b)!
4) c:=!a+b!
1) zmiennoprzecinkowa zmienna ;) b zostanie zamieniona na całkowitą, wynik zostanie przypisany do c
2) błąd - wyrażenie a+b zostanie obliczone jako całkowite, a następnie wynik potraktowany jako jiczba zmiennoprzecinkowa (chociaż wcale nią nie jest) i zamieniony na postać całkowitą. śmieci zostaną przypisane do c. Nie jestem pewien, co zrobi z tym kompilator, być może jednak a+b zostanie obliczone jako zmiennoprzecinkowe, ale wątpię, dla bezpieczeństwa warto stosować to tak. jak w przykładzie 3)
3) a+b zostanie obliczone jako zmiennoprzecinkowe, a zmiennnoprzecinkowy wynik zamieniony na postać całkowitą i przypisany do c
4) błąd, albo i nie, zależy jak na to patrzeć. Na pewno nie zostanie wykonana konwersja do typu całkowitego taka pułapka :) ) zmienna b (całkowita) zostanie zamieniona na postać zmiennoprzecinkową, następnie do wyniku konwersji zostanie dodana wartość a (zmiennoprzecinkowe), wynik (też zmiennoprzecinkowy) zostanie przypisany do c

Składnia E jest trochę niejasna, niby jest to opisane, ale dziwny sposób interpretacji wyrażeń przez kompilator to same problemy.

Moja rada - zapisuj wszystko tak, żebyś nie miał wątpliwości, co się dziele np wyrażenie taki oto zapisane w C:
a = (int) ((a+ b + c) * d / (e - (float) (f))); /* wszystkie zmienne, oprócz "f" i "a", zmiennoprzecinkowe)

W AmigaE zapisz tak:
a := !(!(!(!a+b+c)*d) / (!e - (f!)))!
Dużo tych wykrzykników i nawiasów, ale masz przynajmniej pewność, że bedzie działać dokładnie tak, jak Ty chcesz :)

i bardzo ważna rzecz - liczby (stałe) zmiennopzecinkowe MUSZĄ zawierać kropkę, wobec czego zapis: a := !a + 1 jest błędny, poprawne są a:=!a+1.0; a:=!a+1.

Tylko jeszcze pozostaje kwestia nierozstrzygnięta - co lepsze, połapać się w wykrzyknikach i dopilnować nawiasów, czy wpoić sobie zasady interpretacji wyrażeń przez kompilator. Ja wybrałem tą pierwszą opcję i nigdy nie używałem bardziej skomplikowanej składni niż ta w przykładzie.
Duża ilość nawiasów i wykrzykników nie ma wpływu na wydajność, tam, gdzie ma się wykonać konwersja, to się wykona, tam gdzie nie, to nie ;)
moje zaasady zapisu wyrażeń zmiennoprzecinkowych:
wszystkie konwersje LONG->float wrzucam w nawiasy, czyli (a!), (!a!), (!(!a+b)!), ((a+b)!)
jeżeli mam róźne operatory grupuję w osobnych nawiasach np: !(!(!a + b + c) * (!d - e - 1.0) * 2.7) - 1.0. Nie wiem jak to napisać ;) , chodzi o to, żeby nie pisać np. !a+b*c, tylko !a+(!b*c), działa tak samo, ale łatwiej się połapać (przynajmniej mi)

No i to chyba by było na tyle.
Przesiadka na CreativE powinnna być bezbolesna , różnic prawie brak, a działa lepiej np. w E Woutera kilka rzeczy, które POWINNY działać, po prostu nie działały.

W sumie dlatego przesiadłem się na C, tam jest wszystko jasne. No prawie wszystko i z tej okazji mam super zagadkę (pytanie jak najbardziej poważne):
Jak w C zadeklarować wskaźnik na tablicę wskaźników na struktury? (wszystko oprócz zawartości struktur jest stałe, znaczy na stałe zafixowane w programie), w asm umiem i ma to wyglądać mniej więcej tak:
SECTION CODE
(...)
wskaznik: LONG tablica
tablica: LONG struktura1, struktura2, struktura3, 0
struktura1: LONG #dana1, #dana2
struktura2: LONG #dana1, #dana2
struktura3: LONG #dana1, #dana2

no i ma to działać tak, że mogę uzyskać swobodny dostęp do już zainicjowanych danych.
[#6] Re: OxyPatcher i AmigaE

@shg, post #5

Wow! Zaskoczyłeś mnie aż tak wyczerpującą odpowiedzią! Uważam że mógłby to być spokojnie kolejny odcinek kursu "E". Dużo konkretnych i wartościowych rzeczy. Na pewno nie tylko ja na tym skorzystam. Dzięki!!

Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem