Autor Zpráva
Misha
Profil *
Ahoj, mám problém s počítáním vysokých čísel. Nefunguje to tak jak bych si přál a už několik hodin marně hledám řešení na fórech.
Mám hodně velké číslo (například): 20100000002000125582123500 a potřebuji jej vydělit jiným číslem (například 85) a výsledek potřebuji na 2 desetinná místa zaokrouhleno dolů.
Vytvořil jsem si toto:
num = 20100000002000125582123500;
num = num / 85;
vysledek = Math.floor(num * 100) / 100;
Problém je, že výsledky dostávám v takovýchto hodnotách 2.36470588258825e+23 a nevím jak s tím dále pracovat.
Poradíte, prosím?
Kajman
Profil
Budete asi muset počítat se stringy. Možná půjde použít něco takového locutus.io/php/bc/bcdiv nebo github.com/MikeMcl/bignumber.js
Joker
Profil
Misha:
Problém je, že výsledky dostávám v takovýchto hodnotách 2.36470588258825e+23 a nevím jak s tím dále pracovat.

On je tam ještě větší problém: Ty výsledky ani nebudou přesné. To je ostatně vidět i v tom příkladu:
Správný výsledek toho výpočtu je
236470588258825006848511,76

PHP spočítalo
236470588258825000000000

U standardního PHP se můžete spolehnout, že se do paměti přesně uloží nejvyšších 14 řádů daného čísla. Dál už to je loterie (tady je náhodou 17 řádů).

Více informací Základní kurz 6: Proměnné (problematiky se týkají i předchozí odstavce, které pojednávají o ukládání čísel v PHP).
Mlocik97
Profil
Joker:
Nereší on náhodou JavaScript?
Bubák
Profil
Mlocik97:
Nejsme ve škole, kde se musí na 100 % splnit zadání. Tady se hledá nejideálnější řešení.
V tomto případě tomu tak s velkou pravděpodobností bude.
Misha
Profil *
Sice se řeší JavaScript, ale v podstatě to odpovídá i na otázku, co kdybych to chtěl řešit pomocí Ajaxu. Každopádně se mi nechce věřit, že by tenhle problém byl neřešitelný.

Kajman - Ten Locutus je zajímavý, ale na to, že potřebuji vydělit dvě čísla mi připadá extrémně těžkopádné řešení přidávat na web rozsáhlé knihovny.
Radek9
Profil
Misha:
na to, že potřebuji vydělit dvě čísla mi připadá extrémně těžkopádné řešení přidávat na web rozsáhlé knihovny
To není o tom, že potřebuješ vydělit dvě čísla. To je o tom, že chceš vydělit veliké číslo a zároveň neztratit přesnost. Běžný double (IEEE 754), který se v JS používá na čísla, je holt omezen (pro pochopení doporučuji tohle video) a pokud chceš něco víc, musíš využit podobnou knihovnu. Osobně doporučuji Kajmanem odkázaný bignumber.js nebo (od stejného autora) big.js.
Misha
Profil *
Radek9:
Ano, ten big.js zrovna zkoumám. Ještě teď řeším variantu s Ajaxem, protože v PHP se mi tohle podařilo vypočítat pomocí funkcí gmp_.
V tomhle případě to pro mě bude asi použitelnější, protože pro jiné účely budu stejně potřebovat tahat něco z databáze přes ajax, takže to k tomu jen přihodím... ale přemýšlím, které řešení by bylo lepší použít, kdybych nic dalšího přes ajax netahal.

Při představě, že knihovna se bude uživatelům stahovat vždy (respektive při cachování alespoň při první návštěvě), ikdyž ji nebudou potřebovat a oproti tomu ajax si vyvolá výsledek skutečně jen, když je potřeba.
Co myslíte vy?
Radek9
Profil
Misha:
ale přemýšlím, které řešení by bylo lepší použít, kdybych nic dalšího přes ajax netahal.
To záleží. :-) Chceš, aby ten výpočet proběhl rychleji? (Ajax má zpoždění a při zahlcení serveru může timeoutnout.) Použij big.js. Nechceš stahovat další knihovny a je pro tebe v pohodě drobné zpoždění a asynchronnost? Klidně použij PHP.

knihovna se bude uživatelům stahovat vždy
Minifikovaná verze big.js má 5,9 kB. Pokud se použije gzip, tak dokonce 2,7 kB. V tom bych problém neviděl. ;-) Navíc můžeš použít CDN.
Keeehi
Profil
Misha:
Tak pokud ti jde jen o dělení a zaokrouhlování a nechceš tahat celou knihovnu, můžeš si to samé co poskytuje ta knihovna napsat sám ručně. Prostě stejně, jak tě to učili ve škole, budeš číst řetězec znak po znaku a postupně dělit. Není to nic extrémně náročného. Knihovna bude nejspíše více optimalizovaná, ale pokud to nepočítáš stále a stále dokola tak ti to bude asi jedno.
Osobně taky nejsem zastánce zbytečného tahání knihoven tam kde to není potřeba ale v tomto případě by mi to asi nevadilo.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0