2easy Posted January 14, 2010 Report Share Posted January 14, 2010 bubu, tu mani gandrīz nobaidīji :P bet... $i = 1152921504606846976; // pow(2, 60) $n = (float) $i; echo gettype($i) . ' ' . gettype($n) . '<br />'; // integer double echo $n == 1152921504606846976 ? 'true' : 'false'; // true tests tika izpildīts uz nano.lv servera, kuram jau pēc phpinfo() pirmās rindiņas var spriest, ka tam ir 64bit cpu System: Linux if24.nano.lv 2.6.26.3-grsec #1 SMP Fri Sep 12 21:25:22 EEST 2008 x86_64 Quote Link to comment Share on other sites More sharing options...
bubu Posted January 14, 2010 Report Share Posted January 14, 2010 Pamēģini tagad skaitli 1152921504606846975. Paskaties, ko tad tev teiks. Ņem vērā, ka floati/doubļi skaitli glabā formā mantisa*2^eksponente. Ja mantisa ir 1 un eksponente 60, tad loģiski, ka tev izdrukāsies true, jo skaitlis 1 ielien 52-bitīgā mainīgā. Kārtējo reizi pareklamēšu linku: What Every Computer Scientist Should Know About Floating-Point Arithmetic. Ja notiek darbošanās ar floatiem/doubļiem, tad tā linka izlasīšana ir obligāta. Quote Link to comment Share on other sites More sharing options...
2easy Posted January 14, 2010 Report Share Posted January 14, 2010 bubu, es nomainīju uz 1152921504606846975, kā tu teici, un viss bija tieši tāpat... kr4 it works! np tieši tāpēc es cenšos pēc iespējas pārbaudīt/izpildīt pat samērā vnkāršu kodu, jo šad tad tas ko teorētiski iedomājos atšķiras no tā, kas ir praktiski ;) pat apskatīju šādu debug info abiem šiem skaitļiem echo decbin(1152921504606846976) . '<br />'; // 1000000000000000000000000000000000000000000000000000000000000 echo decbin(1152921504606846975) . '<br />'; // 111111111111111111111111111111111111111111111111111111111111 bet varbūt vajag savādāku testu? man vnk likās, ka ja es pēc float kasta šo vērtību salīdzinu ar sākotnējo int vērtību un tās sakrīt, tad ar to pietiek, lai secinātu, ka (float) neko nav sabojājis. varbūt tev ir kāda 64bit sistēma, kur šāds float kasts pakāš zīmīgos ciparus? Quote Link to comment Share on other sites More sharing options...
endrju Posted January 14, 2010 Report Share Posted January 14, 2010 Jebkurā gadījumā, es uzskatu, ka ir jālieto (float) pie float un (int) pie integera. Neņemot vērā bubu pieminēto, Tu nevari paredzēt kā (float) nākotnē uzvedīdīsies. Piemēram, tas var sākt izdot pilnu decimālskaitli, t.i., veseliem skaitļiem, likt .0 galā. Quote Link to comment Share on other sites More sharing options...
2easy Posted January 14, 2010 Report Share Posted January 14, 2010 (edited) bubu, tev taisnība! sākot no 53bit sākas prikoli :D function ev($v) {echo (is_bool($v) ? ($v ? 'true' : 'false') : gettype($v) . ':' . $v) . '<br />';} // echo val ini_set('precision', 20); // pow(2, 40) +/-1 ev((float) 1099511627775); // double:1099511627775 ev((float) 1099511627776); // double:1099511627776 ev((float) 1099511627777); // double:1099511627777 // pow(2, 50) +/-1 ev((float) 1125899906842623); // double:1125899906842623 ev((float) 1125899906842624); // double:1125899906842624 ev((float) 1125899906842625); // double:1125899906842625 // pow(2, 55) +/-1 ev(36028797018963967); // integer:36028797018963967 ev(36028797018963968); // integer:36028797018963968 ev(36028797018963969); // integer:36028797018963969 ev((float) 36028797018963967); // double:36028797018963968 ev((float) 36028797018963968); // double:36028797018963968 ev((float) 36028797018963969); // double:36028797018963968 // pow(2, 60) +/-1 ev(1152921504606846975); // integer:1152921504606846975 ev(1152921504606846976); // integer:1152921504606846976 ev(1152921504606846977); // integer:1152921504606846977 ev((float) 1152921504606846975); // double:1152921504606846976 ev((float) 1152921504606846976); // double:1152921504606846976 ev((float) 1152921504606846977); // double:1152921504606846976 ev(1152921504606846975.0); // double:1152921504606846976 ev(1152921504606846976.0); // double:1152921504606846976 ev(1152921504606846977.0); // double:1152921504606846976 // neskatoties uz to, salīdzināšana joprojām ir "pareiza" ev(1152921504606846975 == 1152921504606846975.0); // true // tagad gan vairs ne ^^ ev((string) 1152921504606846975 == (string) 1152921504606846975.0); // false es to pamanīju tikai tad, kad gribēju notestēt qn() kaujas apstākļos (uz mysql bigint) izrādījās, ka kaut arī salīdzināšana ar tādu pašu int ir true, taču outputojot uz string/file tā vērtība "apaļojas" (kverijā nokļūst nepareiza vērtība). tb šajā brīdī tad beidzot pakāšas tie zīmīgie cipari/biti kārtējo reizi apstiprinās tas, ka viss ir jātestē ;) viens tests neko nedeva, bet cits jau atklāja gļukus... update... function qi($i) {return is_null($i) ? 'NULL' : preg_replace('/[^\d-]/', '', $i);} // query int val - sagatavo big integer (over 32bit) for mysql query function qn($n) {return is_null($n) ? 'NULL' : (float) $n;} // query num val - sagatavo skaitli for mysql query function qs($s) {return is_null($s) ? 'NULL' : "'" . mysql_real_escape_string($s) . "'";} // query str val - sagatavo tekstu for mysql query function go($sSql) { // mysql query ar error reportingu $h = mysql_query($sSql) or die('<b>mysql error ' . mysql_errno() . ':</b> ' . mysql_error() . '<br /><b>query:</b> ' . substr($sSql, 0, 1000)); return $h; } ini_set('precision', 20); go('DROP TABLE IF EXISTS t'); go('CREATE TABLE t (i bigint) ENGINE=MyISAM'); go('INSERT t (i) VALUES ' . '(1152921504606846975),' . // ar šo vērtību viss ok '(' . qn(1152921504606846975) . '),' . // šeit notiek "apaļošanās" '(' . qi(1152921504606846975) . '),' . // tagad atkal viss ok '(123.0000000000)' // specially for endrju ;) ); $h = go('SELECT * FROM t'); while ($r = mysql_fetch_object($h)) echo $r->i . '<br />'; /* 1152921504606846975 1152921504606846976 1152921504606846975 123 */ Neņemot vērā bubu pieminēto, Tu nevari paredzēt kā (float) nākotnē uzvedīdīsies. Piemēram, tas var sākt izdot pilnu decimālskaitli, t.i., veseliem skaitļiem, likt .0 galā. un hai liek galā, cik nulles grib (kaut vai 10) :D:D:D Edited January 14, 2010 by 2easy Quote Link to comment Share on other sites More sharing options...
endrju Posted January 14, 2010 Report Share Posted January 14, 2010 '(123.0000000000)' // specially for endrju ;) un hai liek galā, cik nulles grib (kaut vai 10) :D:D:D Nē, nu ja esi drošs par automātisku typecasting (float->int) iekš SQL, tad ok. Tikpat labi viņš (SQL) varēja failot ar kļūdu par tipu nesaderību. Quote Link to comment Share on other sites More sharing options...
2easy Posted January 14, 2010 Report Share Posted January 14, 2010 bet "viņš" tā nedarīja ^^ Quote Link to comment Share on other sites More sharing options...
rATRIJS Posted January 14, 2010 Report Share Posted January 14, 2010 mmm - neatceros kad būtu JEBKAD lietojis tik lielus skaitļus :) Quote Link to comment Share on other sites More sharing options...
2easy Posted January 14, 2010 Report Share Posted January 14, 2010 (edited) me 2 ikdienišķām lietām pilnīgi pietiek ar int. tas bigint jau ir priekš kkādiem kosmiskiem aprēķiniem :D anyway, labi ka bubu paspīdēja ar savām float zināšanām. vismaz vienu jaunu niansi uzzināju ;) Edited January 14, 2010 by 2easy Quote Link to comment Share on other sites More sharing options...
bubu Posted January 15, 2010 Report Share Posted January 15, 2010 kārtējo reizi apstiprinās tas, ka viss ir jātestē ;) viens tests neko nedeva, bet cits jau atklāja gļukus... Nevis jātestē, bet jadomā ko dari. Ja lieto floatu, tad secinājumi ir acīmredzami, neko testēt nevajag. Salīdzināšana strādāja, jo droši vien php salīdzinaja to int un float'u kā divus float'us. Tb to int'u nokāstoja uz float'u un tad salīdzināja jau nepareizus skaitļus. ikdienišķām lietām pilnīgi pietiek ar int. tas bigint jau ir priekš kkādiem kosmiskiem aprēķiniem :D Nu nez, nez.. Kādai firmai, kas aktīvi kautko darbojās, un viss logojās datubāzē, sasniegt 4 miljardus ierakstu pēc neilga laiciņa nav nepavisam nekas kosmisks. Un ka tik pēc tam nesanāk dārgāk mainīt visu sistēmu (uz int64), nekā laicīgi to jau paredzēt: http://www.twitpocalypse.com/ http://www.macworld.com/article/141146/2009/06/twitpocalypse_twitter.html http://www.wow.com/2008/01/16/apparently-you-can-have-too-much-gold/ http://forums.worldofwarcraft.com/thread.html?topicId=20860799964&sid=1 utt.. Quote Link to comment Share on other sites More sharing options...
2easy Posted January 16, 2010 Report Share Posted January 16, 2010 (edited) Nevis jātestē, bet jadomā ko dari. tā saucās "praktiskā mācīšanās" :)) dažreiz vnkāršāk ir babakstīties nekā lasīt garas teorijas un iedziļināties tehniskās uzbūves niansēs, lai gan tas, protams, ir ļoti noderīgi Salīdzināšana strādāja, jo droši vien php salīdzinaja to int un float'u kā divus float'us. Tb to int'u nokāstoja uz float'u un tad salīdzināja jau nepareizus skaitļus. true. es jau ar to iedomājos, bet pagaidīju, lai tu pasaki ^^ Nu nez, nez.. Kādai firmai, kas aktīvi kautko darbojās, un viss logojās datubāzē, sasniegt 4 miljardus ierakstu pēc neilga laiciņa nav nepavisam nekas kosmisks. ja logo nevis failā, bet db (droši vien lai ērtā/ātrāk būtu kko meklēt), tad nekādu id tur tāpat nevajag. id lieto lai selectētu/updeitotu/dzēstu konkrētu rindu, bet logfailu skatās daudzas rindas vienlaikus, neko neupdeito, un dzēš arī daudzas rindas vienlaikus. so whats the point from id here? hmm, mb es pārāk burtiski sapratu "viss logojās datubāzē"? tad forget last paragraph :D Un ka tik pēc tam nesanāk dārgāk mainīt visu sistēmu (uz int64), nekā laicīgi to jau paredzēt: attiecībā uz mysql, cik dārgi ir pāris "ALTER TABLE t MODIFY id bigint"? attiecībā uz php nekas nav jāmaina, jo uz 64bit sistēmas šādam int jau ir vajadzīgais izmērs. turklāt get/post parametros šīs vērtības vsp ceļo kā stringi vienīgi tajās valodās, kur ir strikti datu tipi un nav izmantots alias (piemēram, c valodā varētu lietot: typedef int id_t; kur vnk int būtu jānomaina ar int64_t), tur gan nākas repleisot visas vietas, kur ir definēts šis id mainīgais, uz lielāku datu tipu un pēc tam pārkompilēt programmu http://www.twitpocalypse.com/ http://www.macworld....se_twitter.html jā, twitter gan ir labs piemērs! ;) gj bubu http://www.wow.com/2...-too-much-gold/ http://forums.worldo...860799964&sid=1 tajā wow vienā int bija sadzīti veseli 3 resursu veidi (gold/silver/copper), tāpēc daudz ātrāk nepietika vietas. vnk wow koderi pārcentās ar data space optimizēšanu :D Edited January 17, 2010 by 2easy Quote Link to comment Share on other sites More sharing options...
bubu Posted January 17, 2010 Report Share Posted January 17, 2010 attiecībā uz mysql, cik dārgi ir pāris "ALTER TABLE t MODIFY id bigint"? Runa nav jau par MySQL, bet par dīvainu php kodu - piemēram, taviem kāstiem uz float'u. Lielākā sistēmā ej un sazin cik laika prasīs iziet cauri visam kodam un atrast visas šādas "gudrās" programmētāju dīvainības... jā, twitter gan ir labs piemērs! ;)gj bubu nesaprotu, kur ir problēma? Tas ļoti labi demonstrē, kur noved domāšana, ai man jau ar 2.1 (vai 4.2) miljardiem pietiks visam mūžam.. tajā wow vienā int bija sadzīti veseli 3 resursu veidi (gold/silver/copper), tāpēc daudz ātrāk nepietika vietas. vnk wow koderi pārcentās ar data space optimizēšanu :D Tas ir viens un tas pats resursu vieds - nauda. 100 copperi = 1 silvers, 100 silveri = 1 golds. Tāpat kā lati un santīmi nav divi resursu veidi, bet ir viens un tas pats. Neredzu iemesla glabāt santīmus un latus divos dažādos mainīgajos/laukos Quote Link to comment Share on other sites More sharing options...
2easy Posted January 17, 2010 Report Share Posted January 17, 2010 (edited) 100 copperi = 1 silvers, 100 silveri = 1 golds un 1000 goldi ir 3$, iepērkoties pie ķīniešu gold farmeriem :D:D:D zna4it pietiek ieinvestēt tajā geimā ap 700$, lai izraisītu overflow :P Edited January 17, 2010 by 2easy Quote Link to comment Share on other sites More sharing options...
2easy Posted January 17, 2010 Report Share Posted January 17, 2010 (edited) Runa nav jau par MySQL, bet par dīvainu php kodu - piemēram, taviem kāstiem uz float'u. Lielākā sistēmā ej un sazin cik laika prasīs iziet cauri visam kodam un atrast visas šādas "gudrās" programmētāju dīvainības... nebija mērķis iegūt float kā tādu, bet gan no datiem "skaitlis" izmest liekos/kaitīgos simbolus, lai tie nenokļūst līdz sql protams, to var izdarīt ar regulāro izteiksmi kā qi() gadījumā, taču gribējās kko vnkāršāku/ātrāku un izšķīros par labu (float) http://php.net/manual/en/language.types.string.php String conversion to numbers If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 tieši tas, kas man bija vajadzīgs (līdz tam nebiju apskatījis gadījumu ar int64/bigint, jo vēl nebiju to lietojis) es arī mācos rakstīt komentārus, lai citiem būtu vieglāk saprast. varbūt tgd ir progress ;) qi() - query int64 - sagatavo lielu veselu skaitli (int64) ievietošanai mysql query qn() - query num - sagatavo skaitli (int/float) ievietošanai mysql query qs() - query str - sagatavo tekstu (any string) ievietošanai mysql query <- lai būtu saprotamāk qi() - query int val - sagatavo big integer (over 32bit) for mysql query qn() - query num val - sagatavo skaitli for mysql query qs() - query str val - sagatavo tekstu for mysql query function qi($i) {return is_null($i) ? 'NULL' : preg_replace('/[^\d-]/', '', $i);} // query int64 - sagatavo lielu veselu skaitli (int64) ievietošanai mysql query function qn($n) {return is_null($n) ? 'NULL' : (float) $n;} // query num - sagatavo skaitli (int/float) ievietošanai mysql query function qs($s) {return is_null($s) ? 'NULL' : "'" . mysql_real_escape_string($s) . "'";} // query str - sagatavo tekstu (any string) ievietošanai mysql query nu jā, un, protams, ir jāzin konteksts, kādā šīs funkcijas tiek lietotas: no ārpuses pienāk dati (user input), kuriem ir jābūt kādā no standarta formātiem int64/skaitlis/teksts, taču tie var tādi nebūt un/vai saturēt nevēlamu/kaitīgu kodu, kas ir jāneitralizē. un tieši to arī dara šīs funkcijas. qi() lieto tikai samērā retos speciālgadījumos. parasti pietiek ar otrām divām funkcijām qn() qs(). so simple! ;) vsp man ir ļoti izdevīgi, ka tu kritizē katru sīkumu. it makes me do better and better... :)) paldies Tev, bubu Edited January 17, 2010 by 2easy Quote Link to comment Share on other sites More sharing options...
bubu Posted January 17, 2010 Report Share Posted January 17, 2010 Ja kas, tad kāpēc vispār uztraukties datu sagatavošanu kverijam/eskeipošanos, ja sen jau var lietot parametru bindošanu MySQL kverijos? Atkrīt jebkādas problēmas par intu/floatu lielumu, par pēdiņām vai citiem simboliem stringos, utt.. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.