Diskuze: Nepřesné násobení vysokými čísly - špatně zvolené datové typy?
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 11 zpráv z 11.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
V čem máš čísla uložený? Ve floatu?
Desetinný čísla jsou uložený tak, že maj přesnost jen na několik
platných číslic - podle toho, jak velkej typ použiješ.
Float to má cca 7 platných číslic, pokud do něj uložíš i celý číslo větší než tuším 16 777 216, tak ti to už může vrátit jiný číslo, než jsi tam uložil, aniž bys s ním dělal nějaký výpočty.
na tohle by jeste mohl stacit double, kam az ty cisla muzou rust?
Operátor modulo % lze použít pro libovolný celočíselný typ.
2350000000 je mimo rozsah signed 32bit intu -> budto unsigned nebo 64bit int.
Pořád se tam můžeš potýkat se zaokrouhlovacími chybami, což je dáno tím, jak jsou interně desetinná čísla uložena v paměti (viz IEEE 754). Vzhledem k jejich reprezentaci třeba není možné přesně uložit čísla jako dvě desetiny – protože nejdou rozložit na konečný součet (byť i záporných) mocnin dvojky.
Pokud potřebuješ přesnost na relativně málo desetinných míst, můžeš desetinná čísla reprezentovat čísly celými. Pokud třeba potřebuješ být přesný na pět des. míst, prostě místo jednotek pracuj se statisíci (v zásadě vše vynásobíš 100000, abyses s des čísly vůbec nesetkal). Pokud ti bude stačit 64bitový integer, tak máš vyhráno.
Navíc, počítání s celými čísly je výrazně rychlejší než z desetinnými (pokud nevyužiješ paralelizační možnosti procesoru či grafické karty).
Int, long, unsigned, unsigned long jsou stále mimo rozsah. Proto při převodu z větší hodnoty která je mimo rozsah na menší dochází k nesmyslné hodnotě. Aby si mohl provést operaci modulo s velkou hodnotou, použij datový typ long long, nebo unsigned long long. Tyto typy jsou podporovány od verze C99. Pro výpis pomocí printf() long long použij specifikaci formátu %lli, pro unsigned long long použij specifikaci formátu %llu.
Např:
printf("%lli\n", ((long long)(a*b)) % x);
Díky za všechny odpovědi i věcné připomínky. Inu, nováček se sám vytrestal tím, že poznatky o syntaxi a datových typech céčka čerpal pouze z prvního českého zdroje, který mu strejda Google vyplivl - tak o půlce zde zmíněných typech jsem neměl ani páru.
Díky Lubošovi za okamžité a věcné odpovědi, díky DarkCoderovi za syntaxi, jako řešení ale nakonec označím Martina. Myslím, že jeho návrh výrazně zkrátil toto vlákno a šetří čas i nervy ostatních přispěvatelů, protože okamžitým převodem na celá čísla předejdu dalším problémům, které bych zde jinak konzultoval.
Zobrazeno 11 zpráv z 11.