» »

PHP uganka (master level)

PHP uganka (master level)

technolog ::

Zdravo fantje, par dni nazaj sva se s kolegom ukvarjala s tole uganko.

Kdo si upa napovedat, kaj koda izpiše, brez, da bi jo pognal?

$a = "2d9";
$a++;
$a++;
echo $a;


p.s.: Kdor bo goljufal, naj ne piše v to temo.

Senitel ::

731? Zdej grem pa preverit... :)

Missed... Ampak v retrospektivi je čisto logično zakaj je rezultat tak (in tisti, ki piše tako kodo bi ga bilo treba zbrcat).

Zgodovina sprememb…

  • spremenil: Senitel ()

arjan_t ::

Senitel je izjavil:

731? Zdej grem pa preverit... :)

sem mislil isto ampak ni

tako random obnasanje kode je res odlicna stvar

Senitel ::

Obnašanje ni čisto nič random...

sensei ::

No, kaj se pa zgodi s stringom ko mu pristejemo +1 ali ga inkrementiramo v phpju? Kaj postane a po inkrementaciji in kaj po a+1?

arjan_t ::

Senitel je izjavil:

Obnašanje ni čisto nič random...


kako ne? increment dela drugace ce naletis na eno vrednost ki jo kr pretvori v nekaj drugega?

technolog ::

Jap, pravilno bi blo 731, če bi bil string s spredaj 0x:

0x2d9

Ampak ni. Sentinel, si zihr, da veš zakaj je tako? Pazi, spremenljivko povečaš dvakrat.

Zgodovina sprememb…

micka15 ::

2d1?

Senitel ::

Operator spremenjlivki ne more spremenit tipa (razen assignment in casti). Torej $a je vedno string. Za prvi $a++ PHP poskuša ugotovit, kaj je $a in ugotovi, da je lahko edino string (ker nimaš spredaj 0x prefixa). Tule piše, da PHP za stringe uporablja Pearl convention. Obravnava črke in številke, črke so črke, številke so številke. Iz 9 se obrne na 0 in mora naredit increment na znaku prej in iz d dobi e in konča. $a je torej string "2e0".
Naslednji $a++ spet poskuša ugotovit kaj je v $a in tokrat mu rata. "2e0" je čisto veljaven zapis za float (2 + 10^0) in torej 2 poveča za 1 in $a = "3".
Čudoviti svet jezikov, ki niso strong typed...

technolog ::

micka15, zakaj to, zakaj bi se številka v bistvu zmanjšala?

Sentinel, to ni stvar tipiziranja. Maš šibko tipizirane jezike, ki so čisto ok (ruby), lahko bi pa eventuelno naredil močno tipiziran jezik, pri katerem bi ga pač operator ++ konkretno sral. Gre se za dizajn jezika in njegove konvencije.

Zgodovina sprememb…

micka15 ::

>micka15, zakaj to, zakaj bi se številka v bistvu zmanjšala?
v moji glavi je šlo tko
najprej maš string 2d9
prvi increment vidi da je zadnja cifra 9 in jo poveča za 1, dobi 10, ampak ker je po 9 črka nima kaj s tisto enko in dobiš 2d0
naslednji jo pa pač spet za ena poveča

Mipe ::

Sentinel ima prav. Treba je misliti kot računalnik in postopek izvesti korak za korakom. Da malo poenostavim...

$a = "2d9" - string
$a++; - tu najprej skuša ugotoviti, s čim ima opravka, katerega tipa je. V tem primeru privzame šestnajstiško število (ne glede na 0x predznak), torej 2d9 + 1= 2e0.
$a++; - na tem koraku je 2e0, to je lahko ali šestnajstiško število ali pa dvojka z eksponentom 0. V primeru PHP-ja privzame eksponent, ker ni 0x predznaka, zato 2e0 + 1 = 2 + 1 = 3.

Tudi mene je to nekoliko presenetilo, zato sem preveril v živo...

Zgodovina sprememb…

  • spremenil: Mipe ()

arjan_t ::

ni ne privzame da je sestnajtisko, prvic naredi obicajen strin increment (z -> aa, f9 -> g0)

to je kot da bi ti navaden ++ na stevilu pri dolocenih vrednostih se obnasal drugace

technolog ::

Mipe, ti si že malo pozabil, kako se sešteva v bazi 16 :) Namig: 9 + 1 = a

Zgodovina sprememb…

Mipe ::

Ja, prav imata, že dolgo nisem programiral v PHPju. To je že muzejski primerek... :P
V Javascriptu test = "2d9" in test++ postane NaN, neveljaven podatek. Po drugi strani test + 1 postane "2d91", ker pri seštevanju, kjer je vpleten string, pač oba obravnava kot stringa.

Senitel ::

Tole se zgodi v ozadju:
$a = "2d9";
echo is_numeric($a)."\n";
$a++;
echo is_numeric($a)."\n";
$a++;
echo is_numeric($a)."\n";

phyro ::

2db?

look another reason to avoid it! :D

technolog ::

Zakaj ni noben reku 4?

To je drugi pravilni odgovor, če spremeniš
$a++;

v
$a += 1;

Zgodovina sprememb…

Nerdor ::

V Ruby-u kaj takega ni možno izvesti.
1. nima inkrement operatorja (lahko ga sam napišeš)
2. direktno a = a + 1 ne gre, ker Ruby smatra a kot string in takoj sproži napako
3. možno je izvesti a = a.to_i + 1 in ne a = a.to_s + 1

Če se izvede
a = a.to_i + 1
puts a #vrne 3


Ker upošteva pri a.to_i le do prvega string, ki je možno v št. pretvoriti. Gleda od leve proti desne, torej samo 2, od "d" odreže
... for lifetime!

Zgodovina sprememb…

  • spremenil: Nerdor ()

technolog ::

Ni res. Funkcija puts vrne nil, ne 3.

Si offtopic.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Nakupovalni voziček, seje in update količine?

Oddelek: Izdelava spletišč
51334 (1146) phyro
»

PHP in objektno programiranje (strani: 1 2 )

Oddelek: Programiranje
8512158 (10625) kivi113
»

[java]parseInt težava

Oddelek: Programiranje
81037 (940) fiction
»

Visual basic noob question

Oddelek: Programiranje
111573 (1328) DonMatejo
»

Iskanje naslednje ponovitve - najboljši algoritem (strani: 1 2 )

Oddelek: Programiranje
724454 (3512) Thomas

Več podobnih tem