Skocz do zawartości

  • Zaloguj korzystając z Facebooka Zaloguj korzystając z Twittera Zaloguj przez Steam Zaloguj poprzez Google      Logowanie »   
  • Rejestracja

Witamy w Nieoficjalnym polskim support'cie AMX Mod X

Witamy w Nieoficjalnym polskim support'cie AMX Mod X, jak w większości społeczności internetowych musisz się zarejestrować aby móc odpowiadać lub zakładać nowe tematy, ale nie bój się to jest prosty proces w którym wymagamy minimalnych informacji.

  • Rozpoczynaj nowe tematy i odpowiedaj na inne
  • Zapisz się do tematów i for, aby otrzymywać automatyczne uaktualnienia
  • Dodawaj wydarzenia do kalendarza społecznościowego
  • Stwórz swój własny profil i zdobywaj nowych znajomych
  • Zdobywaj nowe doświadczenia

Dołączona grafika Dołączona grafika

Guest Message by DevFuse
 

Zdjęcie

Problem z floatround


Najlepsza odpowiedź grankee, 30.12.2014 13:06

Z floatround jest wszystko w porządku, problem jest inny.

funkcja floatround przyjmuje jako pierwszy parametr zmienną lub stałą float, a kompilator niestety nie wie, że 301/100( a w momencie kompilacji nawet nie wiadomo jakie będą wartości, bo będą tu zmienne) to wyjdzie float i w efekcie otrzymujesz tutaj 0, bo przeznaczono dla wyniku zmienną typu int, a floatround zaokrągla to do 1(bo w górę). Float będzie wtedy jak podzielisz float przez jakąś liczbę, wtedy kompilator wie "aha dzieli float więc wyjdzie też float" i przeznacza mu odpowiedni typ zmiennej.

ShowSyncHudMsg(id, SyncHudObj, ".:|Stopien : %s|:.", ranga[floatround((float(poziom[id]+1)/100), floatround_ceil)]);
Przejdź do postu


  • Nie możesz napisać tematu
  • Zaloguj się, aby dodać odpowiedź
10 odpowiedzi w tym temacie

#1 pro100wHS

    Pomocny

  • Użytkownik

Reputacja: 13
Początkujący

  • Postów:70
  • GG:
  • Lokalizacja:Ziemia
Offline

Napisano 29.12.2014 13:51

Witam. Zbytnio się nie bawiłem z liczbami zmiennoprzecinkowymi, ale postanowiłem zacząć.

Zacznę od omówienia do czego ma to służyć. Każdy gracz posiada posiada pewną zmienną(załóżmy np. poziom[33]). Zmienna ta przyjmuje wartość od 0 do 400. Wartość ta jest liczbą całkowitą. Chciałem, aby na podstawie tej zmiennej graczowi była przypisywana ranga. Stworzyłem więc takie "cudo":

new const ranga[6][]={
"Ranga I",
"Ranga II",
"Ranga III",
"Ranga IV",
"Ranga V",
"Ranga IV"
}

Następnie w hudzie dałem wyświetlanie tej rangi w zależności od wartości zmiennej poziom[id]. Otrzymałem takie coś:

ShowSyncHudMsg(id, SyncHudObj, ".:|Stopien : %s|:.", ranga[floatround((poziom[id]+1)/100, floatround_ceil)]);

Dałem tam poziom[id]+1, żeby nie było dzielenia 0 przez 100

 

Oraz patrząc na budowę floatround widać, że dałem zaokrąglanie w górę. Teoretycznie, jeżeli zmienna poziom[id] przyjmie wartość np.  300 to floatround powinno zwrócić 4. Tak się jednak nie dzieje, bo non stop przy zmiennej poziom[id] większej niż 100 zwraca tę samą wartość(nie zmienia się ranga). Postanowiłem więc pominąć wyświetlanie rangi, ustalić stałą wartość pod poziom[id] oraz zmienić formatowanie tekstu(na wyświetlanie liczb). Otrzymałem więc:

ShowSyncHudMsg(id, SyncHudObj, ".:|Stopien : %d|:.", floatround((300+1)/100, floatround_ceil));

Wyświetliło:

 

.:|Stopien : 1|:.

I proszę mi powiedzieć, jaki ja tu błąd zrobiłem? floatround konstruowałem wg dokumentacji amxx


  • +
  • -
  • 0

b_350_20_FFFFFF_ACBB53_0A0F2E_000000.png

Jeżeli masz do mnie jakąś sprawę to napisz od razu o co ci chodzi.

Wiadomości typu "pomożesz?" bez wyjaśnienia sprawy będę od razu usuwał


#2 grankee

    Godlike

  • Support Team

Reputacja: 507
Wszechwiedzący

  • Postów:1500
  • Lokalizacja:Radom
Offline

Napisano 30.12.2014 13:06   Najlepsza odpowiedź

Z floatround jest wszystko w porządku, problem jest inny.

funkcja floatround przyjmuje jako pierwszy parametr zmienną lub stałą float, a kompilator niestety nie wie, że 301/100( a w momencie kompilacji nawet nie wiadomo jakie będą wartości, bo będą tu zmienne) to wyjdzie float i w efekcie otrzymujesz tutaj 0, bo przeznaczono dla wyniku zmienną typu int, a floatround zaokrągla to do 1(bo w górę). Float będzie wtedy jak podzielisz float przez jakąś liczbę, wtedy kompilator wie "aha dzieli float więc wyjdzie też float" i przeznacza mu odpowiedni typ zmiennej.

ShowSyncHudMsg(id, SyncHudObj, ".:|Stopien : %s|:.", ranga[floatround((float(poziom[id]+1)/100), floatround_ceil)]);

Użytkownik grankee edytował ten post 30.12.2014 13:07

  • +
  • -
  • 2

#3 pro100wHS

    Pomocny

  • Autor tematu
  • Użytkownik

Reputacja: 13
Początkujący

  • Postów:70
  • GG:
  • Lokalizacja:Ziemia
Offline

Napisano 30.12.2014 16:47

Dzięki wielkie. Nie przypuszczałem, że w tym miejscu trzeba zastosować float. Próbowałem przez

new float:zmienna = floatround(dalszy kod)

 

Ale też nie działało. Teraz natomiast wszystko ładnie śmiga. Jeszcze raz dzięki :)

 

Łap 3 plusy ;)


  • +
  • -
  • 0

b_350_20_FFFFFF_ACBB53_0A0F2E_000000.png

Jeżeli masz do mnie jakąś sprawę to napisz od razu o co ci chodzi.

Wiadomości typu "pomożesz?" bez wyjaśnienia sprawy będę od razu usuwał


#4 GwynBleidD

    Godlike

  • Administrator

Reputacja: 1849
Godlike

  • Postów:3066
  • Steam:steam
  • Lokalizacja:Przemyśl
Offline

Napisano 30.12.2014 18:24

Ciekawostka:
operacje na floatach są dużo mniej optymalne, niż na liczbach rzeczywistych. Dlatego:
ShowSyncHudMsg(id, SyncHudObj, ".:|Stopien : %s|:.", ranga[(poziom[id]+1)/100 + ((poziom[id]+1) % 100 > 0)]);
Jest lepszym wyjściem. Jak to działa?
Najpierw dzielimy całkowitą liczbę poziom[id] zwiększoną o 1 przez 100, program w tym miejscu zwróci liczbę zaokrągloną jak wiadomo w dół. Dodatkowo obliczymy resztę z tego samego dzielenia i jeśli jest ona większa od 0, dodamy jedynkę do wcześniejszego wyniku z dzielenia. (operatory logiczne zwracają 0 dla fałszu i 1 dla prawdy, więc jeśli warunek jest spełniony, otrzymamy 1).

Zwykle nie ma to znaczenia, ale czasem może mieć. Zależy jak często wykonuje się ta funkcja. Polecam gorąco unikać floatów kiedy tylko się da :)
  • +
  • -
  • 1
NIE pomagam na PW. Nie trudź się, na zlecenia nie odpiszę... Od pomagania jest forum.
NIE zaglądam w tematy wysłane na PW. Jeśli są na forum to prędzej czy później je przeczytam. Jeśli mam co w nich odpisać, to odpiszę.
 
1988650.png?theme=dark

#5 pro100wHS

    Pomocny

  • Autor tematu
  • Użytkownik

Reputacja: 13
Początkujący

  • Postów:70
  • GG:
  • Lokalizacja:Ziemia
Offline

Napisano 30.12.2014 21:03

Ciekawostka:
operacje na floatach są dużo mniej optymalne, niż na liczbach rzeczywistych. Dlatego:

ShowSyncHudMsg(id, SyncHudObj, ".:|Stopien : %s|:.", ranga[(poziom[id]+1)/100 + ((poziom[id]+1) % 100 > 0)]);
Jest lepszym wyjściem. Jak to działa?
Najpierw dzielimy całkowitą liczbę poziom[id] zwiększoną o 1 przez 100, program w tym miejscu zwróci liczbę zaokrągloną jak wiadomo w dół. Dodatkowo obliczymy resztę z tego samego dzielenia i jeśli jest ona większa od 0, dodamy jedynkę do wcześniejszego wyniku z dzielenia. (operatory logiczne zwracają 0 dla fałszu i 1 dla prawdy, więc jeśli warunek jest spełniony, otrzymamy 1).

Zwykle nie ma to znaczenia, ale czasem może mieć. Zależy jak często wykonuje się ta funkcja. Polecam gorąco unikać floatów kiedy tylko się da :)

 

Wyrzuca w kompilatorze tag mismatch, ale rangę pokazuje odpowiednią. 

 

Mam tylko pytanie, jak dokładnie działa to:

(poziom[id]+1)/100 + ((poziom[id]+1) % 100 > 0)

Np podstawiając 200 pod zmienną poziom[id]

Z pierwszego nawiasu otrzymamy 2.01, ale z tego drugiego wyjdzie takie coś:

 (201 % 100 > 0)

Jakie ma zastosowanie ten % ?


  • +
  • -
  • 0

b_350_20_FFFFFF_ACBB53_0A0F2E_000000.png

Jeżeli masz do mnie jakąś sprawę to napisz od razu o co ci chodzi.

Wiadomości typu "pomożesz?" bez wyjaśnienia sprawy będę od razu usuwał


#6 grankee

    Godlike

  • Support Team

Reputacja: 507
Wszechwiedzący

  • Postów:1500
  • Lokalizacja:Radom
Offline

Napisano 31.12.2014 02:48


ShowSyncHudMsg(id, SyncHudObj, ".:|Stopien : %s|:.", ranga[(poziom[id]+1)/100 + ((poziom[id]+1) % 100 > 0)]);

Powinno być nie %s tylko %d, bo pokazujemy liczbę całkowitą, a nie ciąg znaków.

 

 

 

Ciekawostka:
operacje na floatach są dużo mniej optymalne, niż na liczbach rzeczywistych. Dlatego:

ShowSyncHudMsg(id, SyncHudObj, ".:|Stopien : %s|:.", ranga[(poziom[id]+1)/100 + ((poziom[id]+1) % 100 > 0)]);
Jest lepszym wyjściem. Jak to działa?
Najpierw dzielimy całkowitą liczbę poziom[id] zwiększoną o 1 przez 100, program w tym miejscu zwróci liczbę zaokrągloną jak wiadomo w dół. Dodatkowo obliczymy resztę z tego samego dzielenia i jeśli jest ona większa od 0, dodamy jedynkę do wcześniejszego wyniku z dzielenia. (operatory logiczne zwracają 0 dla fałszu i 1 dla prawdy, więc jeśli warunek jest spełniony, otrzymamy 1).

Zwykle nie ma to znaczenia, ale czasem może mieć. Zależy jak często wykonuje się ta funkcja. Polecam gorąco unikać floatów kiedy tylko się da :)

 

 

 

Sprytne, przyznam, że nie wpadłbym na to :)

Chociaż powinno być zamiast

(poziom[id]+1) % 100 > 0) 

które zwraca true/false a nie 1/0

((poziom[id]+1) % 100 > 0)?1:0) 

które zwróci 1/0 :) Pewnie oba zadziałają, ale żeby nie czytać warninga przy kompilacji...

 

 

 

Panie prosto w glowe, działa to bardzo prosto:

na bardziej przejrzystym przykładzie

(liczba/100)+(((liczba % 100)>0)?1:0)

całe wyrażenie składa się z:

(liczba/100)

to jest jasne, wyrażenie ma wartość dzielenia, ale zaokrąglone w dół tj ucina ułamek po przecinku więc dowolna liczba między 300 a 400 zwróci 3

 

oraz

(((liczba % 100)>0)?1:0)

to jest reszta z dzielenie tzn

301%100 da nam reszte 1, bo 300/100 daje okrągłe 3, a było 301 więc reszta z dzielenia jest 1. Jak będzie 302 to reszta będzie 2 itd, a to wyrażenie sprawdza czy reszta z dzielenie jest większa od 0, jeśli tak to całe wyrażenie zwraca 1, jeśli nie to 0. Jeśli zwróci 1 to znaczy, że taka liczba jako float byłaby zaokrąglona w górę, dlatego dodać 1.


Użytkownik grankee edytował ten post 31.12.2014 02:50

  • +
  • -
  • 1

#7 GwynBleidD

    Godlike

  • Administrator

Reputacja: 1849
Godlike

  • Postów:3066
  • Steam:steam
  • Lokalizacja:Przemyśl
Offline

Napisano 31.12.2014 02:54

Można też tak:
_:(poziom[id]+1) % 100 > 0)
I również pozbędziemy się tag mismatch.
  • +
  • -
  • 1
NIE pomagam na PW. Nie trudź się, na zlecenia nie odpiszę... Od pomagania jest forum.
NIE zaglądam w tematy wysłane na PW. Jeśli są na forum to prędzej czy później je przeczytam. Jeśli mam co w nich odpisać, to odpiszę.
 
1988650.png?theme=dark

#8 grankee

    Godlike

  • Support Team

Reputacja: 507
Wszechwiedzący

  • Postów:1500
  • Lokalizacja:Radom
Offline

Napisano 31.12.2014 02:55

Zawsze musisz powiedzieć ostatnie słowo...grrrr nie lubię Cię ;P

 

 

skoro _: łyka każdy rodzaj zmiennych to czy nie jest dla niej przeznaczane więcej miejsca w pamięci niż dla int?


Użytkownik grankee edytował ten post 31.12.2014 03:09

  • +
  • -
  • 0

#9 pro100wHS

    Pomocny

  • Autor tematu
  • Użytkownik

Reputacja: 13
Początkujący

  • Postów:70
  • GG:
  • Lokalizacja:Ziemia
Offline

Napisano 31.12.2014 10:56

grankee, kiedyś taki nick miałem i już z sentymentu taki wybrałem na tym forum :)

 

już się obawiałem, że was nie zrozumiem, ale jednak jakoś poszło :)

 

 

 

Powinno być nie %s tylko %d, bo pokazujemy liczbę całkowitą, a nie ciąg znaków.

Tylko, że ja chcę, alby z nawiasu kwadratowego zwracało liczbę całkowitą. Potem, żeby według tej zwróconej liczby dopasowywało napis ze zmiennej ranga. Tak więc wyświetlany będzie tekst(%s), nie liczba(%d lub %i). Liczbę wyświetlałem tylko w testach, żeby sprawdzić działanie kodu :)

 

Chyba pytań więcej nie mam. 


  • +
  • -
  • 0

b_350_20_FFFFFF_ACBB53_0A0F2E_000000.png

Jeżeli masz do mnie jakąś sprawę to napisz od razu o co ci chodzi.

Wiadomości typu "pomożesz?" bez wyjaśnienia sprawy będę od razu usuwał


#10 GwynBleidD

    Godlike

  • Administrator

Reputacja: 1849
Godlike

  • Postów:3066
  • Steam:steam
  • Lokalizacja:Przemyśl
Offline

Napisano 31.12.2014 12:34

skoro _: łyka każdy rodzaj zmiennych to czy nie jest dla niej przeznaczane więcej miejsca w pamięci niż dla int?


_: to właśnie int :) W ten sposób po prostu rzutujemy zmienną typu boolean na inta i dzięki temu kompilator wie, że robimy to świadomie i nie wyrzuca warninga.
  • +
  • -
  • 0
NIE pomagam na PW. Nie trudź się, na zlecenia nie odpiszę... Od pomagania jest forum.
NIE zaglądam w tematy wysłane na PW. Jeśli są na forum to prędzej czy później je przeczytam. Jeśli mam co w nich odpisać, to odpiszę.
 
1988650.png?theme=dark

#11 grankee

    Godlike

  • Support Team

Reputacja: 507
Wszechwiedzący

  • Postów:1500
  • Lokalizacja:Radom
Offline

Napisano 31.12.2014 15:35

Dobra, 1:0 dla Ciebie :D


  • +
  • -
  • 1




Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych