Autor | Zpráva | ||
---|---|---|---|
oxidián Profil * |
#1 · Zasláno: 7. 2. 2015, 18:22:14
Nevíte jaký je zdrojový kód pro funkci round? Zajímá mě jakým způsobem lze dělit s přesností na dvě nebo na tři místa.
|
||
Yuff.3 Profil |
#2 · Zasláno: 7. 2. 2015, 18:23:19
Mám taký pocit, že toto popísal aj djmetla vo svojom videu - nájdeš to na google - neviem či by sa to nebralo ako reklama preto sem nedávam presný link.
|
||
smitka Profil |
#3 · Zasláno: 7. 2. 2015, 18:32:41
A/B na 2 místa:
intval( (A+0.5) *10 / B ) /10 A/B na 3 místa: intval( (A+0.5) *100 / B ) /100 |
||
oxidián Profil * |
#4 · Zasláno: 7. 2. 2015, 18:35:05
Yuff.3:
To video bylo kde na youtube? Co mám hledat? "djmetla video round php" mi nic nedává smitka co je B? |
||
Yuff.3 Profil |
#5 · Zasláno: 7. 2. 2015, 18:37:22
skús len djmetla (eu) a v serialoch nájdi video - má tam len jedno v ktorom sa zaoberá php - základy php
|
||
oxidián Profil * |
#6 · Zasláno: 7. 2. 2015, 18:46:27
Tak jo shledl jsem video, malem sem z toho oslepl ale dobre, no aspon už umím nastavit ptoměnnou a spočítat $a+$b. To co chci tam ale není
|
||
smitka Profil |
#7 · Zasláno: 7. 2. 2015, 19:14:33
oxidián:
B je dělitel 10/6 intval(10+0,5)*10/6)/10 intval(105/6)/10 intval(17,777)/10 17/10 = 1,7 |
||
Alphard Profil |
#8 · Zasláno: 7. 2. 2015, 19:25:41
Aneb jak to zkomplikovat co nejvíc. Na tohle má funkce round() druhý parametr.
|
||
smitka Profil |
Alphard:
Tak otázka byla na zdrojový kód zaokrouhlování a toto je jeden z možných alogoritmů - přičítání 0.5 se reálně používá. Předpokládám, že dokumentaci k funkci v php si zvládne přečíst každý. |
||
Alphard Profil |
#10 · Zasláno: 7. 2. 2015, 20:10:44
smitka:
„Předpokládám, že dokumentaci k funkci v php si zvládne přečíst každý.“ Je to smutné, ale velká část dotazů na tomto fóru by se vyřešila přečtením dokumentace. Doporučuji spíš přístup snažit se z dotazu odhadnout reálný problém a pomoct ho řešit, není třeba tazatele podporovat ve špatný řešeních. |
||
oxidián Profil * |
#11 · Zasláno: 7. 2. 2015, 20:11:23
smitka:
vůbec tě nechápu. Jaký dělitel? Syntaxe round: float round ( float $val [, int $precision = 0 [, int $mode = PHP_ROUND_HALF_UP ]] ) Kde máš $val a kde máš $precision v tom tvém kódu? Dělitel v syntaxi není. |
||
smitka Profil |
#12 · Zasláno: 7. 2. 2015, 20:49:03
Alphard:
Máš pravdu, šel jsem přímo k problému - dělit 2 čísla na určený počet desetinných míst. oxidián: Dával jsem do příkladu dělení 2 čísel (jako zlomek) na x desetinných míst, jak ses ptal - musíš dělit A/B => dělenec dělitelem. Pokud chceš přímo zaokrouhlování $val (desetinné číslo) na $precision míst, tak: $x = 10^$precision;//10,100,... intval( $val * $x + 0.5) / $x např. 1.666666 na 1 místo intval( 1.666666 * 10 + 0.5) / 10 intval( 17.16666 ) / 10 17 / 10 = 1,7 |
||
Jan Tvrdík Profil |
#13 · Zasláno: 7. 2. 2015, 21:05:15
smitka:
Pozor na to, že ^ v PHP není umocnění, ale bitový XOR. Operátor umocnění je ** (dostupný od PHP 5.6).
|
||
oxidián Profil * |
#14 · Zasláno: 7. 2. 2015, 21:07:41 · Upravil/a: oxidián
Dobře tak už to chápu. Takže mi výjde číslo s jednou desetinnou čárkou, a pak to musím celé zopakovat bez desítky, abych dostal celé číslo.
dík Ale můj počítač to stejně není schopen spočítat: num = 254.454300; mi vrátí 254.449997 hloupý počítač :-) |
||
Alphard Profil |
#15 · Zasláno: 7. 2. 2015, 21:35:42
Ach jo, zatím 15 příspěvků kvůli takové trivialitě.
oxidián: echo round(254.454300, 2); // 254.45 smitka [#12]: Viz [#13] Jan Tvrdík, neber si to špatně, ale vymýšlet složitá řešení (i kdyby fungovala) tazatelům, kteří to evidentně nepochopí a blbě použijí, je k ničemu. „Nevíte jaký je zdrojový kód pro funkci round?“ Zřejmě tento github.com/php/php-src/blob/fc33f52d8c25997dd0711de3e07d0dc260a18c11/ext/standard/math.c#L139 (nejsem si 100% jistý). |
||
oxidián Profil * |
#16 · Zasláno: 7. 2. 2015, 22:10:16
Už to je vyřešeno. Použil jsem smitkovo řešení ale s precision = 1; tedy bez dělení. Je to rychlejší. Mě šlo o to že jsem nechtěl použít funkci. Funkce volané zevnitř cyklu dost nepříjemně zpomalují běh programu. Celkem jsem odstranil 2 funkce na zaokrouhlování a výsledek byl dvounásobné ušetření času.
|
||
smitka Profil |
#17 · Zasláno: 7. 2. 2015, 23:39:32
Alphard:
Tak tazatel tady evidentně pochopil o co jde, pokud jde o obyčejné zaokrouhlení, tak je mnohem rychlejší přičít 0.5 a oříznout desetinnou část - to mi nepřijde jako vymýšlení složitého řešení a je to princip, který se běžně používá, protože je velmi rychlý. Myslím, že programátor by tyto triky měl znát. Jan Tvrdík: Pravda, neuvědomil jsem si (pracuji ve více jazycích), naštěstí byl princip jasný. Díky za upozornění. Vhodnější by tedy bylo: $x=array(1,10,100,1000,10000,10000); intval( $val * $x[$precision] + 0.5) / $x[$precision] Jsem názoru, že nemusí být vždy dobré používat vestavěné univerzální funkce, když potřebuji konkrétní jednoduchou věc. Mohl bych klidně napsat i do dělení a násobení pomocí bitových posunů a trochu sčítání/odčítání, což je opět velmi rychlé: function deleno10($val) { $q = ($val >> 1) + ($val >> 2); $q = $q + ($q >> 4); $q = $q + ($q >> 8); $q = $q + ($q >> 16); $q = $q >> 3; $r = $val - ((($q << 2) + $q) << 1); return $q + ($r > 9); } function krat10($val){ return ($val << 3) + ($val << 1); } Někdy může být ++i rychlejší než i++. Bohužel takové věci už dnes skoro nikdo neřeší, výkonu je prý dost... |
||
Jan Tvrdík Profil |
#18 · Zasláno: 7. 2. 2015, 23:45:11
smitka:
Řešit takové věci v PHP je dost zbytečné, tohle není C. Pokud potřebuješ řešit rozdíl mezi ++i a i++, tak sis vybral špatný jazyk. |
||
smitka Profil |
#19 · Zasláno: 8. 2. 2015, 00:03:18
Jan Tvrdík:
Neříkám, že toto řeším v PHP, říkám jen, že hlubší znalost toho jak funkce fungují dělá lepší programátory. |
||
Alphard Profil |
#20 · Zasláno: 8. 2. 2015, 01:41:00
smitka [#17]:
Uznávám, že v tomto případě to nakonec pomohlo a moje rada nebyla příliš přínosná. Ale objektivně, z příspěvků výše to nešlo předvídat a statisticky je přínosnější můj přístup. Zapomněl jsem, že je to ten samý člověk, se kterým jsme před rokem řešili nějaké konvoluce obrazů. Za mnoho let zpátky si nevzpomínám na nikoho jiného, kdo by měl důvod zabývat se rychlostí round() (řešení s intval je rychlejší o 23 %). Samozřejmě už tehdy jsme mu říkali, že PHP na tohle není zrovna vhodný jazyk a stále si myslím, že by bylo lepší úsilí vynaložené na optimalizaci zaokrouhlování vynaložit do studia C, ale to je jeho věc. „Bohužel takové věci už dnes skoro nikdo neřeší, výkonu je prý dost...“ Protože k tomu mají důvod, volání tvé superfunkce deleno10() je až 10x pomalejší než nativní dělení /. Taky se divím, že to lidé v PHP nepoužívají častěji. „Neříkám, že toto řeším v PHP, říkám jen, že hlubší znalost toho jak funkce fungují dělá lepší programátory.“ To nikdo nerozporuje, jen tvrdíme, že ušetřit pár procent výkonu není to nejdůležitější. |
||
Davex Profil |
#21 · Zasláno: 8. 2. 2015, 02:16:54
smitka:
„hlubší znalost toho jak funkce fungují dělá lepší programátory“ To ano, ale většina programátorů nepotřebuje vědět jak to funguje, protože to za ně vyřešili jiní. V C má optimalizaci dělení nebo násobení konstantou na starosti překladač, který to udělá mnohem lépe než by to udělala většina programátorů. Například k vynásobení deseti potřebuje pouze dvě instrukce ( $x = $val + 4 * $val a $x + $x ) a k vydělení deseti použije trik s násobením magickou konstantou a posunem (($val * 3435973837) >> 35 ).
K pomalosti tvých rozepsaných výpočtů se už vyjadřoval Alphard. |
||
smitka Profil |
#22 · Zasláno: 8. 2. 2015, 14:39:46
"Superfunkcí na dělení" jsem nechtěl demonstrovat nejrychlejší postup pro dělení, ale ukázat, že lze spousty úloh řešit jiným způsobem. Násobením a dělením pouze ukazuji, že lze tyto úlohy řešit i bez použití násobení a dělení, které jsou na některých platformách neporovnatelně náročnější než bitové posuny a sčítání.
Je pravda, že pro PHP vývojáře na x86 je to naprosto nezajímavé a offtopic. Omlouvám se za to. |
||
Časová prodleva: 9 let
|
0