Diskuze: Rýchle počítanie s veľkými číslami
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 7 zpráv z 7.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.
když se ti to nejvejde do Long, tak můžeš rozložit výpočet a ukládat si to do Stringu, ale nedokážu říct, zda to je rychlejší než BigInteger
BigInteger je, alespoň v .NETu, velmi dobře optimalizovaná struktura. Zároveň je bezpečná a spolehlivá. Nevím, zda by specificky tento úkol šel matematicky udělat nějakou rychlejší cestou přes string, nicméně bych ti doporučil bigint.
Zamyslím-li se, tak jako zrovna 105 je celkem v pohodě, protože je to ta desítka, za kterou se ti kumulují nuly, jak víc a víc násobíš, takže by to šlo řešit cestou "dvojího násobení" - v hlavní cestě násobíš čísla a odtrhuješ nulové řády, jejichž exponent pak násobíš v té druhé cestě, a ve finálním výpisu to dáš dohromady. Teoreticky by se tato možnost dala aplikovat na jakákoliv čísla ve "věděcké notaci" a ukládat do typu double, ale hrozilo by znepřesnění výpočtu kvůli desetinné čárce, pokud by čísel bylo moc.
P.S. Vědecká notace = 3278.2 = 3.2782e3 = 3.2782 * 103
Pánové, opravdu?
Jelikož tohle je typický "školní" příklad, tak trik je čistě
matematický. Čísla řádu 105, dokonce i vynásobená mezi sebou,
se do
long
bohatě vejdou a víc nepotřebujete, protože Základní pravidla modulární aritmetiky.
Můžete modulovat po každém násobení, dokonce každé to číslo
samotné před tím násobením, což většinou značně sníží jeho řád, a
pokud modulujete všechno stejným číslem, celkový výsledek se nezmění.
Ďakujem, toto by teda malo fungovať?
s:=1;
for j:=a to a+x-1 do begin
s*=k[j];
s:=s mod m;
end;
writeln(s mod m);
end;
alebo aj toto?
for j:=a to a+x-1 do s*=(k[j] mod m);
Lépe bude fungovat to první, protože v tom druhém Ti s
bude
pořád narůstat, i když o něco pomaleji a na konci ho pak musíš ještě
zmodulovat do výsledné podoby. Naopak u toho prvního držíš celé
s
pravidelnou modulací v přiměřeném rozsahu a po skončení
cyklu už ho ani modulovat nemusíš.
Pro jistotu tedy:
s:=1;
for j:=a to a+x-1 do begin
s*=k[j];
s:=s mod m;
end;
writeln(s); # s již prošlo mod na konci cyklu
end;
P.S.: Nejlepší bude, když si sám napíšeš nějakou krátkou řadu
malých čísel a zkusíš si to spočítat, jestli to sedí.
Zobrazeno 7 zpráv z 7.