Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno Datový typ pro práci s penězi

Ahoj,

kvůli binární chybě při počítání s desetinnými čísly by se měl hlavně při práci s penězi používat speciální datový typ, který tuším ve většině jazyků je, nebo existuje jiná náhrada. Ten speciální datový typ je Decimal.
Běžně tedy ve floatu např. 0.2 + 0.1 = 0.30000000000000004 a u Decimal to je správně Decimal('0.2') + Decimal('0.1') = Decimal('0.3')

V mnoha knihách, článcích a i od lidí mám právě informaci, že typ Decimal by se měl používat jen při té práci s peněžními částkami, kde je potřeba mít opravdu přesné počty.
Nevím, jestli na to mám špatný pohled, ale já bych nejradši ten datový typ Decimal používal pořád, ať už pro práci s penězi, tak i pro obyčejné počty, protože ani při běžné práci s počty se mi nelíbí, že se občas ta binární chyba projeví na výsledku a já pak musím zaokrouhlovat. Podporuje Decimal všechny matematické operace jako obyčejný float, nebo je něco, co se s Decimal nedá dělat?
Nebo je to špatný návyk to používat?

Věnuju se programování krátkou dobu, takže budu rád za vaše rady a zkušenosti s tím.

Díky.

Předmět Autor Datum
https://en.wikipedia.org/wiki/Decimal_data_type Decimal ti umozni (v nejakem rozsahu) presne scitat…
gilhad 04.07.2021 01:59
gilhad
Stovku rovným dílem rozdělit mezi 3 lidi v obchodě nedokážu. Chci jen tazateli naznačit, že žádný da…
hynajs 04.07.2021 11:37
hynajs
Nekde je to decimal, někde decimal, u kterého definujes počet desetinnych mist, jinde je to currency…
Jan Fiala 04.07.2021 06:09
Jan Fiala
Pokud pocitas s penezma na halere (procenta, urokovani) a delas komercni appku, tak vzdy Decimal...
MaSo 04.07.2021 12:31
MaSo
To urcite ano, pokud nejde o nejakou zvlaste oduvodnenou vyjimku. Ale IMHO otazka znela jinak - zda… poslední
gilhad 04.07.2021 19:01
gilhad
Ok, díky za reakce. :-)
Quake01 04.07.2021 14:54
Quake01

https://en.wikipedia.org/wiki/Decimal_data_type

Decimal ti umozni (v nejakem rozsahu) presne scitat, odcitat a nasobit cisla s desetinymi castmi a prace s penezi byl jeden z duvodu pro jeho vytvoreni. Takze se casto pro praci s penezi doporucuje a mnohdy je to i spravna volba. (A mnohdy taky ne.) A jde pouzit i pro jine vypocty (ale taky ne vzdy je to nejlepsi volba).

Jinak Decimal je v ruznych jazycich implementovan ruzne, take ma ruznou presnost (pocet mist, na ktere je schopen korektne pocitat). Vetsinou jsou vypocty s nim o neco pomalejsi, ale pokud nepracujes s prilis mnoha daty, tak to roli asi hrat nebude - a spatne pouzity algoritmus muze znamenat mnohem horsi vykonnost.

Napriklad Decimal("1") / Decimal("3") se ti ze zjevnych duvodu nikdy nespocte spravne a presne. Navic, pokud si u Decimal zadas pocet desetinych mist (nektere jazyky to vyzaduji), tak ti nebude pocitat presneji - napriklad pro 2 desetina mista (pro pocitani s penezi vetsinou dostacujicici) ti vyjde "0.33" misto 0.33333333333333333333333333 co by ti dal float (cili muzes dostat oproti floatu vysledky i vyrazne nepresnejsi) - a samozrejme na takovehle veci casem narazis, kdy treba nekdo zemre a ma tri dedice, co dedi rovnym dilem, a zrovna nezanecha vhodny pocet korun, tak delis 3 a nekde se to musi zaseknout... A i jazyky, kde pocet desetinych mist nezadavas, tak maji nejaky dany implicitne ve sve implementaci.

Decimal (ani float, ani integer) samy o sobe zadne operace nepodporuji, naopak nektere operace (scitani, nasobeni, deleni ...) nejakym zpusobem podporuji praci s nejakymi typy. A typy, ktere ty operace zrovna nepodporuji se vetsinou zkonvertuji na neco, co ty operace podporuji (i kdyz se pri tom muze ztratit nejaka presnost). Napriklad Decimal asi vetsinou nebude primo podporovan goniometrickymi funkcemi (sinus a podobne) protoze se moc nepocita s tim, ze by se s nimi pouzival a presnost byla nadale nutna presne tim zpusobem, ktery Decimal podporuje.

Pro opravdu narocne vypocty se muze stat, ze budou pouzity zcela jine datove typy (napriklad jsem psal typ, ktery ukladal racionalni cisla jako dvojici jmenovatel a citatel a prubezne je optimalizoval (kratil na zakladni tvar), nebo knihovnu pro presnou praci s cisly na desitky tisic mist, nebo knihovnu pro praci se symboly )

Takze jako u vsech typu je potreba se podivat, co dany typ (v danem jazyce a pri danych knihovnach) umoznuje a co ne a pak podle toho zvolit (s tim, ze casto rozumne vyhovuje i vic ruznych typu) - Decimal je pro nektere operace prima, ale rozhodne to neni stribrna kulka, co resi vsechny problemy.

Taky casto nepotrebujes hodnotu "absolutne presnou" ale jen "rozumne presnou" a i kdyz v prubehu vypoctu pouzivas presnost vyssi, tak vysledek nakonec brutalne zaokrouhlis, aby byl vubec pouzitelny. ("Ne ze bych se chtel srovnavat s radioaktivnim uhlikem ...")

Stovku rovným dílem rozdělit mezi 3 lidi v obchodě nedokážu. Chci jen tazateli naznačit, že žádný datový typ problém sám nevyřeší, nýbrž se v kódu musí situace reálně ošetřit. Např. v účetnictví máme účty pro zaokrouhlovací chyby, se zaokrouhlovacími chybami počítá třeba zákon o DPH.

Pro opravdu narocne vypocty se muze stat, ze budou pouzity zcela jine datove typy (napriklad jsem psal typ, ktery ukladal racionalni cisla jako dvojici jmenovatel a citatel a prubezne je optimalizoval (kratil na zakladni tvar), nebo knihovnu pro presnou praci s cisly na desitky tisic mist, nebo knihovnu pro praci se symboly )

Souhlasím, někdy nezbude než počítat se zlomky a zavést třídu s vlastnostmi citatel, jmenovatel a aritmetickými metodami. Ale hotovost se ve zlomcích nevede ani elektronicky, pokud vím.

Nekde je to decimal, někde decimal, u kterého definujes počet desetinnych mist, jinde je to currency nebo money.
Používáš jej tam, kde chceš mít zachovany počet desetinnych mist a nechceš, aby dochazelo k "nepřesnostem" jako u single, float, double apod.
Vyhoda: nedochází k nepřesnostem v desetinne části
Nevyhoda: počet desetinnych mist je omezen obvykle na 4, někde je při prevodu na řetězec automaticky přidáván kód měny.

Používat můžeš kdekoliv, kde uznáš za vhodné, že by se typ hodil a používáš jej stejně jako ostatní necelociselne typy.

To urcite ano, pokud nejde o nejakou zvlaste oduvodnenou vyjimku.

Ale IMHO otazka znela jinak - zda Decimal uplne vsude jako univerzalni supercool datovy typ, nejen u penez?
A na to je odpoved, ze nekde to fungovat bude, nekde jen castecne a s omezenima a nekde vubec ne.

Zpět do poradny Odpovědět na původní otázku Nahoru