Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Kod koji daje neočekivani rezultat

[es] :: Art of Programming :: Kod koji daje neočekivani rezultat

Strane: << < .. 8 9 10 11 12 13 14 15 16 17

[ Pregleda: 107936 | Odgovora: 337 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat18.07.2020. u 12:05 - pre 45 meseci
Da, moleri prave hemiju, kao i sa operatorom %.

Jednakost (-2)%10==(-2) nema nikakvu praktičnu primenu, za razliku od jednakosti (-2)%10==8, koja ima praktičnu primenu. Međutim, neki "genije" je odlučio da u računar ugradi ovo drugo.

Isto tako i ovde. 1.0/0.0 nije NaN, nego INFINITY, dok je 1.0/(-0.0) jednako -INFINITY, pri čemu su to različite vrednosti.

Paran broj nula uz negativne vrednosti je besmislica.

Svojevremeno me je Ivan Dimković ubeđivao da to tako treba jer je u specijalnom slulaju sa dekodiranjem multimedije tako podesnije.

Dobro, u tom slučaju je podesnije, ali u mnogim drugim slučajevima nije, pa se napravi više štete nego koristi.

Nije nikakav problem da se zbog nekakve primene ubaci dodatna operacija. Jedno delenje za to, a drugo delenje za ostalo.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat18.07.2020. u 13:28 - pre 45 meseci
Zahvaljujem se Burgos-u na ispravci. Evo budalaštine:

Code (c):

#include <stdio.h>

int main() {
     double x = 0;
     double y = -x;

     printf("x == %f, y == %f\n", x, y);
     printf("x %s y\n", x==y ? "==" : "!=");
     printf("1/x == %f, 1/y == %f\n", 1/x, 1/y);
     printf("1/x %s 1/y\n", 1/x==1/y ? "==" : "!=");

     return 0;
}
 


x == 0.000000, y == -0.000000
x == y
1/x == inf, 1/y == -inf
1/x != 1/y


Dakle, x == y i 1/x != 1/y, a nije NaN, niti greška zaokrugljivanja.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat31.07.2020. u 19:32 - pre 44 meseci
Windwows-ov Calculator je kod koji daje neočekivan rezultat. Evo:


Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
Prikačeni fajlovi
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat07.04.2021. u 08:23 - pre 36 meseci
Evo jednog koda u prilogu.

Ako se kompajlira sa gcc -O1 ili clang -O1, onda puca ne ispisujući ništa. Ako se kompajlira sa gcc -O2 ili clang -O2, onda ispisuje "Original list has 100000000 elements." i tek onda pukne.

Radi se o optimiyaciji steka, s tim da eliminacija steka u rekurzivnoj funkciji count nije baš jednostavna. fpc ne ume da tako nešto uradi prilikom kompajliranja odgovarajućeg Pascal koda.

Sa eliminacijom steka u funkciji reverseList već ni gcc ni clang ne mogu da se izbore, mada je iterativno obrtanje liste moguće. Jednostavno, kompajleri nisu dovoljno pametni da transformišu taj kod u iterativan. Naravno, to je u slučaju te funkcije i očekivano.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
Prikačeni fajlovi
 
Odgovor na temu

mjanjic
Šikagou

Član broj: 187539
Poruke: 2679



+690 Profil

icon Re: Kod koji daje neočekivani rezultat07.04.2021. u 21:10 - pre 36 meseci
Citat:
Nedeljko:
Windwows-ov Calculator je kod koji daje neočekivan rezultat. Evo:


Nije neočekivan, kod mene radi "normalno" i daje isti rezultat za Standard: otkucaš 2+5, i kad pritisneš zvezdicu na numeričkoj tastaturi, izbaci 7, što kad se pomnoži sa 3 daje 21. Isto se dešava i kada operatore za sabiranje i množenje biraš na samom kalkulatoru umesto na tastaturi.
Kod Scientific verzije "sačeka" da uneseš '2+5*3' i kao rezultat daje 17.
Ne zna, možda im je to bio neki "bug" koji je brzo ispravljen novim ažuriranjem.

Blessed are those who can laugh at themselves, for they shall never cease to be amused.
 
Odgovor na temu

Branimir Maksimovic

Član broj: 64947
Poruke: 5534
dynamic-62-240-24-69.cpe.sn.co.rs.



+1064 Profil

icon Re: Kod koji daje neočekivani rezultat07.04.2021. u 21:41 - pre 36 meseci
Citat:
Nedeljko:
Evo jednog koda u prilogu.

Ako se kompajlira sa gcc -O1 ili clang -O1, onda puca ne ispisujući ništa. Ako se kompajlira sa gcc -O2 ili clang -O2, onda ispisuje "Original list has 100000000 elements." i tek onda pukne.

Radi se o optimiyaciji steka, s tim da eliminacija steka u rekurzivnoj funkciji count nije baš jednostavna. fpc ne ume da tako nešto uradi prilikom kompajliranja odgovarajućeg Pascal koda.

Sa eliminacijom steka u funkciji reverseList već ni gcc ni clang ne mogu da se izbore, mada je iterativno obrtanje liste moguće. Jednostavno, kompajleri nisu dovoljno pametni da transformišu taj kod u iterativan. Naravno, to je u slučaju te funkcije i očekivano.


Sta je ovde cudno, program sa undefined behavior da puca?
Meni je najveci grad duhova bio kada sam u cpp fajlu definisao struct Data a da nije u anonimnom namespaceu. MS ima u afx*.h libu struct Data forvard deklaraciju i implementaciju u nekom libu.
To je izazvalo takve nepredvidjene rezultate da sam izgubio 5 sati dok nisam provalio u cemu je fazon. Ono sto je meni tu super interesantno je na koju foru je VC povukao definiciju strukture
iz drugog fajla a da nije prijavio nikakvu gresku ;)
 
Odgovor na temu

Branimir Maksimovic

Član broj: 64947
Poruke: 5534
dynamic-62-240-24-69.cpe.sn.co.rs.



+1064 Profil

icon Re: Kod koji daje neočekivani rezultat07.04.2021. u 22:14 - pre 36 meseci
Elem da objasnim u cemu je fazon, Radi se o strict aliasingu. Znaci kompajler podrazumeva da se radi o pointeru na strukturu a ne samo na pointeru na pointer. Zbog toga nesto mulja
dok optimizuje i verovatno kesira po registrima. Imao sam slican bug kod jednog lika re 10 godina, upravo na implementaciji linked liste i tog prvog noda koji je maskirao pointerom, pa je popravka
bila da se pointer kvalifikuje kao volatile da bi se sprecilo to kesiranje u registrima.

edit:
ma zaboravi ovo sto sam napisao, u tvom slucaju je obicno probijanje steka rekurzijom ;)
Sad probao i skapiram da je na Linux-u stek premali za milion rekurzivnih poziva ;)
ulimit -s kolko_treba i reseno

[Ovu poruku je menjao Branimir Maksimovic dana 08.04.2021. u 00:10 GMT+1]
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat08.04.2021. u 09:10 - pre 36 meseci
Branimir Maksimovic

Da, probijanje steka rekurzijom. Nema undefined behavior-a.

Ono što je neočekivano, je da ne puca funkcija count(), koja je takođe rekurzivna. Zapravo ona puca bez optimizacija, a ne puca sa optimizacijama.

Dakle, kompajler ima optimizacije sa kojima uspeva da eliminiše rekurziju u funkciji count(), dok to ne uspeva sa funkcijom reverseList().
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Branimir Maksimovic

Član broj: 64947
Poruke: 5534
dynamic-62-240-24-69.cpe.sn.co.rs.



+1064 Profil

icon Re: Kod koji daje neočekivani rezultat08.04.2021. u 09:54 - pre 36 meseci
Tail call recursion to je kada se rekurzivni poziv radi sa jump umesto sa call posto se onda rekurzija prakticno pretvara u petlju. No kod mene sa -O1 puca i count.
E sad, da nema undefined behavior, da, program je 100% po propisu. Nema casta nema prljavih zezalica ;)

edit:
evo nerekurzivne verzije te dve f-=je ;)
Code:

void reverseList(List*list)
{
    List rc = NULL;
    List i = *list, j = (*list)->next;
    for(;j;i=j,j=j->next){
        i->next = rc;
        rc = i;
    }
    i->next = rc;
    rc = i;
    *list = rc;    
}
int count(List list)
{
    int rc = 0;
    while (list) {
        list = list->next;
        rc++;
    }
    
    return rc;
}


nisam stavio proveru u reverse ako je lista prazna ili sa jednim elementom :P



[Ovu poruku je menjao Branimir Maksimovic dana 08.04.2021. u 11:08 GMT+1]

[Ovu poruku je menjao Branimir Maksimovic dana 08.04.2021. u 11:10 GMT+1]
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.loc.akton.net.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat08.04.2021. u 11:06 - pre 36 meseci
Pa, u prvoj poruci sam napisao da puca i count() pri -O1, odnosno da sa -O1 ne ispisuje ništa. Takođe, nije problem napisati obe funkcije nerekurzivno, ali onda ova tema ne bi bila obrađena - sa manje optimizacije puca, a sa više optimiozacije radi dobro (barem count() funkcija).

Međutim, interesantno je kako je kompajler bio dovoljno pametan da eliminiše rekurziju u count() funkciji. Ne radi se samo o zameni call sa jump, nego i o nenagomilavanju lokalnih promenljivih. Stek se nagomilava usled pamćenja adrese povratka (usled call, što jump nema), kao i usled lokalnih promenljivih. Treba eliminisati i jedno i drugo.

To bi bilo lako ako se svi izlazi iz funkcije svode na

1. return nerekurzivni izraz;

2. return count(nerekurzivni izraz);

Međutim, ovde rekurzivni poziv glasi

return count(l)+1.

Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Branimir Maksimovic

Član broj: 64947
Poruke: 5534
dynamic-62-240-24-69.cpe.sn.co.rs.



+1064 Profil

icon Re: Kod koji daje neočekivani rezultat08.04.2021. u 11:10 - pre 36 meseci
https://en.wikipedia.org/wiki/Tail_call

Nego, rekurzija mora biti pod kontrolom, zato sto ovakvi problemi dolaze nenadano i tu ne moze nista da se uradi, zbog toga obicno dodas nivo rekurzije
pa ako sei zgubi kontrola opalis exception ili vratis gresku, sto u principu znaci da je nesto poslo naopako.

 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.loc.akton.net.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat08.04.2021. u 13:52 - pre 36 meseci
mjanic

Rezultat je pogrešan i nema tu šta dalje.

Zašto je pogrešan?

Ne postoji fundamentalna greška u tome da se cifra 1 piše kao 5, a cifra 5 kao 1. To je stvar konvencije kako ćemo šta pobeležavati. Možemop se dogovoriti da izbacujemo prioritete matematičkih operacija.

Međutim, postoje konvencije koje se podrazumevaju, a koje se uče u školama širom sveta. Ovo je u suprotnosti sa time.

Drugo, prioritet matmatičkih operacija nije slučajno takav kakav jeste, nego da bi se smanjila potreba za pisanjem zagrada.

Ako imamo artilkle u količinama k1, k2 i k3 sa jediničnim cenama c1, c2 i c3, onda je cena svega k1*c1+k2*c2+k3*c3.

Postoje suprotni primeri, gde bi se pisalo manje zagrada kada bi sabiranje bilo starije od množenja, ali je mnogo više primera gde je zgodnije da množenje bude starije od sabiranja.

Asimetrija između sabiranja i množenja potiče otuda što je sabiranje distributivno u odnosu na množenje, ali množenje nije distributivno u odnosu na sabiranje. Drugim rečima, u opštem slučaju važi

(a+b)*c=a*c+b*c,

ali u opštem slučaju ne važi

a*b+c=(a+c)*(b+c).
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

mjanjic
Šikagou

Član broj: 187539
Poruke: 2679



+690 Profil

icon Re: Kod koji daje neočekivani rezultat13.04.2021. u 02:53 - pre 36 meseci
Ne kontam, ta slika koju si ti postavio može da bude i fotošop, kažem da kod mene radi kako treba, samo što kod standardne verzije ne čeka da uneseš ceo izraz, već čim uneseš npr. 2+3, on to odmah sabere kad pritisneš *, ako hoćeš da ti radi kako ti očekuješ, onda aktiviraš "scientific" (kako, inače, rade ovi 'scientific' digitroni koje koriste u školama i na fakultetima, a za one 'obične' ne znam, možda rade isto, a možda i kao ovaj 'standard' kod Win10).

Dakle, 'Standard' ti jednostavno ne dozvoljava da uneseš izraz npr. 2+5*3, već nakon pri 2+5 odmah izračuna da je to 7 prilikom pritiska *. Dakle, 'Standard' funcioniše tako što izborom bilo kog binarnog operatora (sabiranje, oduzimanje, množenje, deljenje, itd.) digitron izračuna prethodno unet izraz, tj. najčešće binarnu operaciju za prethodno uneta dva broja i odgovarajući operator između njih - praktično kao da si nakon uneta dva broja i operatora između njih pritisnuo =.
Da li je to ispravno ili ne, i ne zanima me, nikad ne koristim 'standard' digitron. Ali, mislim da su oni stari veliki digitroni (koristili se u prodavnicama, a možda ih neko koristi i danas) upravo tako radili (pa mora za mleko i 2 hleba umesto 95 + 40*2 mora da se kuca 95*1+40*2).
Blessed are those who can laugh at themselves, for they shall never cease to be amused.
 
Odgovor na temu

Rapaic Rajko
Bgd

Član broj: 4105
Poruke: 810
31.223.145.*



+62 Profil

icon Re: Kod koji daje neočekivani rezultat14.04.2021. u 13:59 - pre 35 meseci
Ocigledno niko ovde ne pamti vreme od pre kompjutera.

Stvar je vrlo prosta: app Calculator je u osnovnom modu emulacija kancelarijske racunske masine.
A zasto kancelarijska masina radi tako kako radi? Zato sto na svaki pritisnuti operator, masina ispisuje operaciju + argument operacije na traku.
A sta ce nam traka? Pa nekad su se trake s tih masina prilagale u (recimo) bankama (SDK, itd.) prilkom predaje racuna, izvoda, i slicnog - kao dokaz ispravnosti onoga sto pise na dokumentu (najcesce sume).
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat14.04.2021. u 18:56 - pre 35 meseci
Na slici je očigledno "standard".

Ukucaj lepo "2+5*3", tako kako piše, znak po znak i onda pritisni "Enter". Dobićeš 21. To što on nakon unosa zvezdice napiše 7 kao međurezultat i onda nakon pritiska "*3" i "Enter" ispiše "21", ne menja činjenicu da je to pogrešno. To što kalkulator "tako radi" nije opravdanje za pogrešan rezultat. Ako nekada nije bilo tehničkih mogućnosti da se prave mašine koje poštuju prioritet operatora, nije opravdanje za takve kalkulatore na računaru, koji ima potrebne tehničke mogućnosti.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Mihajlo Cvetanović
Beograd

Moderator
Član broj: 37636
Poruke: 1249



+96 Profil

icon Re: Kod koji daje neočekivani rezultat15.04.2021. u 14:05 - pre 35 meseci
To da je ponašanje kalkulatora u standard modu "pogrešno" je samo jedna ocena. Ja očekujem to "pogrešno" ponašanje, jer sam na njega navikao, i ja nisam sam. Možda će promeniti ponašanje kad većina nas matorih izumre...
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat15.04.2021. u 16:49 - pre 35 meseci
Nije samo jedna ocena. To je kao kada bi cifru 5 pisali kao cifru 8 i obrnuto. Jednostavno se u školama uče drugačije konvencije. Ako neki očekuju da je 1+2=5 zato što imaju drugačiju interpretaciju upotrebljenih oznaka, onda su oni ti koji se ne uklapaju u ostatak sveta.

Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Rapaic Rajko
Bgd

Član broj: 4105
Poruke: 810
31.223.145.*



+62 Profil

icon Re: Kod koji daje neočekivani rezultat23.04.2021. u 13:56 - pre 35 meseci
Evo jedan kratak primer/dokaz da je Kalkulator u osnovnom modu emulator kancelarijske racunske masine.

Ukucajte ovako nesto

72
/
12
=

dobicete 6, ocekivano.

A sad ukucajte

36
=

i sta ste dobili?

Nepobitno, Kalkulator (osnovni mod) radi tacno kao (pra)istorijska kanc. masina.
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.dynamic.isp.telekom.rs.



+2789 Profil

icon Re: Kod koji daje neočekivani rezultat24.04.2021. u 21:16 - pre 35 meseci
Radi pogrešno. Sve ostalo je nevažno.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

mjanjic
Šikagou

Član broj: 187539
Poruke: 2679



+690 Profil

icon Re: Kod koji daje neočekivani rezultat25.04.2021. u 20:52 - pre 35 meseci
Ne radi ono što si ti zamislio, pa je zato pogrešno? Ne radi onako kako te naučila učiteljica, pa je zato pogrešno?
Za ono što se uči kod učiteljice nije potreban ovaj digitron u Standard modu, pa i ne mora da radi tako!

Tebi ako se ne sviđa kako radi, aktiviraj Scientific mod, tu radi onako kako ti očekuješ.
Blessed are those who can laugh at themselves, for they shall never cease to be amused.
 
Odgovor na temu

[es] :: Art of Programming :: Kod koji daje neočekivani rezultat

Strane: << < .. 8 9 10 11 12 13 14 15 16 17

[ Pregleda: 107936 | Odgovora: 337 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.