Schnelle Möglichkeit zum manuellen mod eine Zahl
Ich muss in der Lage sein, zu berechnen, (a^b) % c für sehr große Werte von a und b (einzeln schieben begrenzen und die Ursache überlauf-Fehler, wenn Sie versuchen zu berechnen, a^b). Für genügend kleine zahlen, über die Identität (a^b)%c = (a%c)^b%c funktioniert, aber wenn die c zu groß ist das nicht wirklich helfen. Ich schrieb eine Schleife zu tun, die mod-operation manuell, ein zu einer Zeit:
private static long no_Overflow_Mod(ulong num_base, ulong num_exponent, ulong mod)
{
long answer = 1;
for (int x = 0; x < num_exponent; x++)
{
answer = (answer * num_base) % mod;
}
return answer;
}
aber das dauert eine sehr lange Zeit. Gibt es irgendeine schnelle und einfache Möglichkeit, das zu tun diese operation ohne tatsächlich zu nehmen, um die macht von b UND ohne zeitaufwendiges Schleifen? Wenn alle Stricke reißen, kann ich einen bool-array zur Darstellung eines riesigen Daten-Typ und herausfinden, wie dies mit den bitweisen Operatoren, aber es muss einen besseren Weg geben.
- Klingt wie ein Euler-problem... Wenn es ist, Sie sollte deutlich gemacht werden, dass die Frage, anstatt zu versuchen, zu betrügen...
- Die Kenntnis der Palette von a, b und c, die uns helfen könnten.
- Cheat?.........
- Diese bool-array-Idee wird nicht funktionieren. Bool-arrays sind nicht bitvectors, und Sie werden nicht gespeichert gepackt. Plus, dann bist du nicht verlassen auf den direkten hardware-math.
- Projekt Euler #188 ?
- Ich weiß nicht, ob es wirklich Betrug. Das Lesen über das problem, das es aussieht, als würde er die Antwort kennt, er will einfach nur wissen, wie man es in angemessener Zeit-constraints in c#.
- Ich war eigentlich nicht zu lösen versucht, dass problem ist, ich brauche dieses Algorithmus für ein Verschlüsselungs-Programm, das ich Schreibe.
- Ist dies für Ihre eigenen Erbauung, oder wollen Sie tatsächlich sich auf Ihre Algorithmus zu schützen, Ihre Kunden von übeltätern? Wenn der ehemalige, gehen Sie. Wenn letzteres, ich bitte Sie eindringlich, noch einmal zu überdenken.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich denke, du bist auf der Suche nach : http://en.wikipedia.org/wiki/Montgomery_reduction
oder die einfachere Möglichkeit, auf der Grundlage der Modularen Errichtung in die Stufe (aus wikipedia)
if (exponent == 0) break;
tatsächlich verlangsamt es leicht in ein ulong Umsetzung - langen prime test dauert 32.798, ohne es und 32.733 mit es nach auf der zweiten Ausführung; Prüf-base ist etwas langsamer und testen Ergebnis ist ein bisschen langsamer (etwa 33 Sekunden). Manchmal Verknüpfungen sind nicht Optimierungen.Schnell Modularen Errichtung in die Stufe (ich denke, das ist, was es bezeichnet) funktionieren könnte.
Nun, wie du gehst zu tun, die mit Daten-Typen, weiß ich nicht. So lange, wie Ihr Datentyp unterstützen kann, c^2, ich denke, du wirst in Ordnung sein.
Wenn Sie Zeichenfolgen, erstellen Sie einfach string-Versionen addieren, subtrahieren und multiplizieren (nicht zu hart). Diese Methode sollte schnell genug sein, das zu tun. (und Sie können beginnen, Schritt 1 mod c, so dass a nie größer als c).
EDIT: Oh, schau, eine wiki-Seite auf Modularen Errichtung In Die Stufe.
Hier ist ein Beispiel des Schnellen Modularen Errichtung in die Stufe (vorgeschlagen, in einer der früheren Antworten) in java. Sollte nicht zu schwer zu konvertieren, die auf C#
http://www.math.umn.edu/~garrett/crypto/a01/FastPow.html
und die Quelle...
http://www.math.umn.edu/~garrett/crypto/a01/FastPow.java
Python hat pow(a,b,c) liefert (a**b)%c (nur schneller), also muss es etwas cleverer Weg, dies zu tun. Vielleicht machen Sie einfach die Identität, die Sie erwähnt.
Ich würde empfehlen, die überprüfung über die Dezimal-Dokumentation zu sehen, ob es Ihren Anforderungen entspricht, da es einen integrierten Typ und kann mit dem mod-operator. Wenn nicht, dann sind Sie gehen zu müssen, eine beliebige Präzision Bibliothek, wie der java-Bignum.
Können Sie versuchen, factoring 'a' in hinreichend kleinen zahlen.
Wenn die Faktoren 'a' und 'x', 'y' und 'z', dann
a^b = (x^b)(y^b)(z^b).
Dann können Sie Ihre Identität: (a^b)%c = (a%c)^b%c
Scheint es mir, als ob es irgendeine Art von Beziehung zwischen macht und mod. Macht ist nur die wiederholte Multiplikation und der mod ist im Zusammenhang zur division. Wir wissen, dass Multiplikation und division sind die inversen, so dass durch diese Verbindung würde ich davon ausgehen, es gibt eine Korrelation zwischen power und mod.
Zum Beispiel, nehmen Sie die Befugnisse von 5:
Das Muster ist klar, dass 5 ^ b % 4 = 1 für alle Werte von b.
Es ist weniger klar in dieser situation:
Aber es ist immer noch ein Muster.
Wenn Sie konnte, erarbeiten die Mathematik hinter dem Muster, ich wäre nicht überrascht, wenn Sie herausfinden konnten, wird der Wert des mod-ohne dabei die tatsächliche Leistung.
Könnten Sie versuchen, diese:
C#: Dabei ein Modul (mod) den Betrieb auf eine sehr große Anzahl (> Int64.MaxValue)
http://www.del337ed.com/blog/index.php/2009/02/04/c-doing-a-modulus-mod-operation-on-a-very-large-number-int64maxvalue/
Kurzen schreiben Ihre eigenen schnell modularen Errichtung in die Stufe, die einfachste Idee, die ich mit oben kommen kann, ist die Verwendung der F# BigInt-Typ:
Microsoft.FSharp.Math.Types.BigInt
unterstützt, die die Vorgänge mit beliebig großem Maßstab - einschließlich der Potenzierung und modulare Arithmetik.Es ist ein built-in-Typ, wird Teil des ganzen .NET framework mit dem nächsten release. Sie brauchen nicht zu verwenden, F# zu verwenden BitInt - Sie können machen, verwenden Sie es direkt in C#.
Können Sie Faktor a, b, oder c? Hat C eine bekannte Spektrum?
Diese sind 32-bit Ganzzahlen! Gehen Sie bitte diese Website
Zum Beispiel, hier ist, wie man die mod n%d where d 1>>s (1,2,4,8,...)
Dort ist der code für n%d, wobei d 1>>s - 1 (1, 3, 7, 15, 31, ...)
Dies ist nur gehen, um wirklich helfen, wenn c klein ist, obwohl, wie Sie sagte.
Sieht aus wie Hausaufgaben in der Kryptographie.
Tipp: schauen Sie sich Fermat ' s little theorem.