Berechnung aller Summanden der abgewandelten BBP-Formel
i=0:
Dieser Wert gehörte vor der Kommaverschiebung ursprünglich eigentlich zur Vorkommastelle ...
Deren HexaDezimalwerte sind noch ab der 300. Stelle (in unserem neuen Kommabereich) zu berücksichtigen
16^300 · ( 4/(8·0+1) - 2/(8·0+4) - 1/(8·0+5) - 1/(8·0+6) ) =
16^300 · ( 4/1 - 2/4 - 1/5 - 1/6 ) =
16^300 · ( 4 - 1/2 - 1/5 - 1/6 ) ... das führt uns zu dem Nachkommaanteil N0 = 0 - ?1/2 - ?2/5 - ?3/6
um die ?-Werte kümmern wir uns sofort:
?1: 16^300 ist gerade -> 16^300 · 0,5 ist eine ganze Zahl -> Nachkommaanteil ?1=0
?2: 16^300 · 1/5 = 16^300 / 5
Einschub: Nachkommaanteil von (a · b) / n a = (r·n + s) b = (v·n + w) |
Beispiel: (311·498) / 37 311 = (11·37 + 4) 482 = (13·37 + 17) |
||
Das Ausmultiplizieren der beiden Klammern führt fast nur zu Produkten mit dem Faktor n ... (A · n) mit einer Ausnahme: s·w (Rest) (a · b) / n = ( A · n + Rest) / n Für den Nachkommanteil ist ausreichend: Rest / n; Man kann also schon bei den Faktoren die Restbidung (mod n) vornehmen! evtl. ist der Rest größer oder gleich n; das kann am Ende berücksichtigt werden |
(311·498) / 37 = ( A·37 + 4·17) / 37 --> für den Nachkommaanteil entscheidend ist nur (4·17) / 37 = 68 / 37 = 1 + 31 / 37 Nachkommaanteil: 31 / 37 |
?3: 16^300 · 1/6 = 16^300 / 6 ... 16 = 2·6 + 4 ... 4^300 / 6 ist auch nicht viel angenehmer!
Einschub: a^k mod n = Rest der Ganzzahl-Division a^k geteilt durch n Verfahren: k sei gerade: a^k = a^(k/2) · a^(k/2) k sei ungerade: a^k = a^((k-1)/2) · a^((k-1)/2) · a Man zerlegt die so erhaltenen Potenzen immer weiter bis zu einem Punkt, an dem man problemlos den Restwert (mod n) bestimmen kann; dann rechnet man zurück (siehe Beispiel) |
Beispiel: (9^501) mod 37 k ist ungerade 9^501 = 9^250 · 9^250 · 9 = (9^250)^2 · 9 = [(9^125)^2]^2 · 9 = (9^125)^4 · 9 ; Exponent ist ungerade ... 9^125 = (9^62)^2 · 9 Exponent ist gerade ... 9^62 = (9^31)^2 Exponent ist ungerade ... 9^31 = (9^15)^2 · 9 Exponent ist ungerade ... 9^15 = (9^7)^2 · 9 Exponent ist ungerade ... 9^7 = (9^3)^2 · 9 Exponent ist ungerade ... 9^3 = 9^2 · 9 = 81 · 9 jetzt fangen wir an mit der Berechnung "mod 37" 9^3 mod 37 = (81 · 9) mod 37 = (7 · 9) mod 37 = 26 ... und dann geht es damit retur 9^7 mod 37 = [(9^3)^2 · 9] mod 37 = (26^2 · 9) mod 37 = (10*9) mod 37 = 16 9^15 mod 37 = [(9^7)^2 · 9] mod 37 = [16^2 · 9] mod 37 = (34 · 9) mod 37 = 10 9^31 mod 37 = [](9^15)^2 · 9] mod 37 = (10^2 · 9) mod 37 = (26 · 9) mod 37 =12 9^62 mod 37 = (9^31)^2 mod 37 = 12^2 mod 37 = 33 9^125 mod 37 = [(9^62)^2 · 9] mod 37 = [33^2 · 9] mod 37 = (16 · 9) mod 37 = 33 9^501 mod 37 = [(9^125)^4 · 9] mod 37 = [33^4 · 9] mod 37 = [34 · 9] mod 37 = 10; |
Eine entsprechende C#-Routine wäre:
private double Xpow16hN_modM(int n, int m) //
(16 hoch n) mod m ... 16^n mod m
{
double p = 1;
if (n > 1)
{
double r = Xpow16hN_modM(n / 2, m); // rekursiv
if (n % 2 == 0) { p = (r * r) % m; }
else { p = (16 * r * r) % m; }
}
else
{
if (n == 0) p = 1;
else p = 16 % m;
}
return p;
}
damit errechnen wir ?3 = 4
für i=0 erhalten wir also den
Nachkommaanteil N0 = 0 - 0/2 - 1/5 - 4/6 = -26/30 = -13/15
i=1:
Dieser Wert gehört eigentlich zur ursprünglich 1. Nachkommastelle ... Kommawerte davon sind noch nach 299 Stellen (in unserem neuen Kommabereich) zu berücksichtigen
16^299 · ( 4/(8·1+1) - 2/(8·1+4) - 1/(8·1+5) - 1/(8·1+6) ) =
16^299 · ( 4/9 - 2/12 - 1/13 - 1/14 ) =
16^299 · ( 4/9 - 1/6 - 1/13 - 1/14 ) ... das führt uns zu dem
Nachkommaanteil N1 = 16/9 - 4/6 - 9/13 - 4/14 = 0,133089133089133
und so weiter mit
i=2: ... N2
i=3: ... N3
...
i=299: ... N299
Die Summe aller N-Werte ergibt A.