Milyen változótípust használjak?
Éppen szorzatpiramist készítek ANSI C nyelv segítségével. Az első sorban 100-tól 115-ig mennek a számok, a másodikban 100*101, 102*103, stb.
A negyedik sorban már akkora számok vannak, hogy a long típus nem elég neki, túlcsordul.
Próbáltam az unsigned longot, túlcsordul. Próbáltam a long longot, unsigned long longot. Minden esetben túlcsordul, ráadásul mindig ugyanazt a baromságot írja ki, pedig már a long longnak elégnek kéne lennie, 64 biten csak elfér az a szám...
Megnéztem, hogyan csináltuk anno gyakorlaton, ott long double volt a típus, de akkor meg nullát ír ki szorzatnak, az összes esetben. Gyakorlaton is azt írta ki.
Lehet hogy baromság, de még long long double-t is próbáltam :D
Miért ír ki a long double-nél nullát szorzatnak, és miért adja ugyanazt a túlcsordulási értéket a különböző típusmódosítóknál?
bár sebességileg lassabb lesz a program, de miért nem változtatsz a tároláson?
Az egész szám helyett, készíts egy struktúrát két double taggal, tárolnál egy sima double-t ( 1,8761323 azaz 0.00000-tól 9.99999-ig illetve egy számot, ami azt jelölné hogy 10 hányadik hatványával kell szorozni.
A számítás egyszerű lenne, mert a két kis doublet kell összeszoroznod, a másik tagokat pedig szimplán összeadni, lásd:
Legyen a két szám A = 1987 és B = 320000 ->
ekkor a struktárad lenne ->
A->szám = 1.987 és A->szorzó = 3 ( ugye mert 10 a 3.on )
B->szám = 3.2 és B->szorzó = 5 ( mert 10 a 5.on )
Ekkor az új szám ( legyen C )
C->szám = 1.987 * 3.2 és C->szorzó = 3+5
azaz
C->szám = 6.3584 és C->szorzó = 8 ( azaz 10 a 8.on )
Ekkor a valódi szám az : 6.3584 * 10 ^ 8 =
635840000
Lásd az eredeti szám szorzatot: 1987 * 320000
635840000
FONTOS : az megjegyzem, hogy ha A->szám és B->szám szorzata eléri a 10!!!!! akkor abból 1 lesz és 1et hozzá kell adni a szorzóhoz :)
Lásd: 2.0 * 5.0 = 10.0, tárolásilag C->szám = 1.0 C->szorzó = 1 ( mert 10 az elsőn! ), szóval ez az eset fontos :)
remélem segített ( ha nem akarsz külső osztályokat használni vagy a túlcsorduláson aggódni számításnál, hisz amint látod így óriási számok esetén is csak ksi értékkekel kell számolnod :)
( megjegyzés, akinek jobb / kényelemesebb ötlete van, azok engem is érdekelnének, elgondolkoztatott ez :D )
ez de jó :D
Holnap neki is állok, most már zokni vagyok az ilyesmikhez. Persze engem is érdekelnek alternatív megoldások, nem árt ha tanul az ember.
Először arra gondoltam, hogy biztos rosszul írod ki és ott csonkolja le (ll, L pl.).
De a számok a 4. sorban már 10^16 nagyságrendűek - ez 2^53, tehát lassan eléred a 64 bit határát.
Én stringbe írnék saját szorzófüggvényt, a kézzel szorzás alapján.
#6: Pontosság tekintetében mindenképpen veri. Teljesítmény tekintetében pedig igen jó eséllyel alulmarad. A magasszintű nyelvek "nagy szám" típusai általában a sztringes megoldást használják. A double-t én pontosan azért kerülném - bármennyire is érdekes a megoldásod; egyébként maga a double is így működik ugye -, mert számítási hibát eredményezhet, pláne, ha kumulálod a viselkedést. Valószínűleg az adott feladatnak az is az eredeti célja, hogy megmutassa, mi szívást tud okozni a float/double pontatlansága.
Ha jól értem a kérdező célját (soronként összevonunk két-két szomszédos számot), akkor a végső eredmény 100*101*102*103...*115 lesz, ami olyan 2.7E+30, ez pedig 128 biten kényelmesen ki kell, hogy férjen.
#3: Szerintem (3kor tévedhetek) a double-ös megoldásod a precíziót nem növeli (a számjegyeket csak 1 doubleben tárolod), kizárólag a hatványkitevőt.
Még egy olyan megoldás eszembe jutott, hogy tároljunk struktúrában egy "előjelet", egy n számot majd n darab unsigned intet. Így takarékosabb mint stringgel, cserébe bonyolultabb a szorzás, ha 2-es számrendszerben maradunk akkor nehezebb a kiírás...
Áh, értem a pontosságot, felídéztem pár régebbi feladatot, amikor görcsöltem rajta, hogy miért nem jó az értékem, megfelelő képlettel, és a gond csak a float/double szépsége volt :D
Utána fogok nézni ezeknek a sztringes módszereknek, elég érdekesnek / hasznosnak hangzik, kösz az infót :)
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!