Ich habe den Algorithmus nicht allein sondern mit einem Freund entwickelt.
Ausgang ist ein Array[n] wobei n nicht genau die größe der "Stellenanzahl" der zu dividierenden Zahl angibt. Array[i] kann 1, 2 oder 3 stellig sein. Meine Zahlen haben so z.B. 2.000 oder 14.000 Stellen!!!
Also war es geeignet eine schriftliche Division zu bauen:
Code:
void division_big(RESULTS *res, int *i_ptr, int i_len, std::ostream& outfile)
- In meine Fkt. übergebe ich einen struct um die Ergebnisse zu speichern [*res] (uninteressant)
- Einen Pointer auf den Beginn meines Array[n] [*i_ptr]
- Die Anzahl der Zahlen im Array[n] für die Schleife [i_len]
- Die Adresse zum Ausgabefile [outfile] (uninteressant)
Code:
{
int divisors [11] = {3,4,5,7,11,12,13,17,19,37,73}, *i_ptr_divisors;
- Hier sind die Divisoren die ich zum teilen verwende
Code:
i_ptr_divisors = divisors;
- Auf deren Anfangspunt des Arrays setze ich eine pointer das gibt Geschwindigkeit
Code:
int *start_arr;
start_arr = i_ptr;
- Da ich mehr als nur einmal die grosse Zahl dividieren will, merke ich mir den Startpunkt vom Array in start_arr
Code:
int* i = new int(0);
int* j = new int(1);
- Die Variablen sind zum zählen da: i für die Anzahl der Divisonen
- Tue jetzt das folgende für alle Divisoren:
Code:
i_ptr = start_arr; // pointer vom Anfang der Zahl die diviert wird
int k, i_log, i_erg, i_rest=0;
- Am Beginn jedes mal neu auf die gr. Zahl setzten
- k ist ein Zähler für die n Zahlen im Array[n]
- i_log speichert ein Zwischenergebnis
- in i_rest sammel ich die Info welcher Rest, wie bei der schrift. Div. anfällt
Code:
for ( k=0; k<i_len; k++, i_ptr++)
{
- Mache alles folgende für alle Zahlen im Array für den Divisor i
- Der Zähler k geht mit der aktuellen Zahl bis zur Gesamtlänge des Arrays i_len
- i_ptr++ rutsch als Pointer im Array vorwärts
Code:
i_log = log10( *i_ptr )+1;
- Hier ermittel ich die Stellenanzahl der Zahl die gerade aus dem Array genommen wurde: log10 von 1-9 ist 0-0.9... daher ist hier Stelle+1 gerechnet worden.
log10 10-90 ist hier 1 - 1.9... und log10 100-900 ist 2-2.9...
Code:
i_x = pow ( 10, i_log-1 );
- Diese Zeile wird auskommentiert!!!!
- Hier wird jetzt die Stellenanzahl definitiv festgelegt
- Im nachherein würde ich sagen das ist überflüssig ??? denn 0,9; 1,9; oder 2,9 sind + 1 jaweils im integer : 1,2 und 3 was ich ja wollte.
Code:
if ( *i_ptr == 0)
i_log = 1;
- Der Sonderfall: eine Zahl ist gleich 0, ist auch abgefangen. (Es kommt vor das in meinem Array eine Zahl 0 ist.)
Code:
i_erg = ( *i_ptr + pow ( 10, i_log ) * i_rest );
- Hier wird wenn es vorher eine Rest gab dieser zur nachfolgenden Zahl addiert.
- Als erstes wird die Multiplikation dann die Addition ausgeführt somit bleibt die aktuelle Zahl auch bei Rest=0 erhalten.
Code:
i_rest = i_erg%*i_ptr_divisors;
}
- Hier ermittel ich mit modula den Rest nach der Teilung.
(- Ich muss an dieser Stelle sagen: Mich interessiert das Ergebnis als Zahl überhaupt nicht ich möchte nur wissen ob die Zahl durch eine oder mehrere Divisoren teilbar ist.)
Code:
if (i_erg%*i_ptr_divisors == 0) {
switch (*i_ptr_divisors){
case (3): res->results += "3,"; break;
case (4): res->results += "4,"; break;
case (5): res->results += "5,"; break;
case (7): res->results += "7,"; break;
case (11): res->results += "11,"; break;
case (12): res->results += "12,"; break;
case (13): res->results += "13,"; break;
case (17): res->results += "17,"; break;
case (19): res->results += "19,"; break;
case (37): res->results += "37,"; break;
case (73): res->results += "73"; break;
}
- Hier wird jetzt das Ergebnis struct *res gefüllt, wenn der Rest nach der Division aller Zahlen im Array Null ergibt.
Code:
*j = 2;
}
*i +=1;
i_ptr_divisors++;
} while( *i < 11);
- Zähler für den Divisor und i für die schon veranstalteten Divisonen raufsetzten. Fertig.
Code:
if ( *j==1) res->results += "0"; // set zero if nothing is selected or the value is zero
*j = res->results.rfind(","); // to erase the last comma
*i = res->results.length();
if (*j != -1) if ( (*i-*j) ==1 ) res->results.erase( *j, *i);
delete i;
delete j;
outfile<<setfill(' ')<<setw(20)<<left<<res->results;
- Ein bischen Schönheitskorretur bei der Ausgabe: letztes Komma weg löschen
- Die Variablen i und j wieder löschen
- Alles in die Ergebnissdatei schreiben.
Hier mal das Zwischenergebnisse nachdem ich den Quelltext wie folgt abgewandelt habe:
Code:
...stuff
do{
i_divisors = divisors[t];
i_ptr = start_arr;
int k, i_log, i_erg, i_rest=0;
outfile<<endl<<"divisor "<<i_divisors<<endl;
for ( k=0; k<i_len; k++, i_ptr++)
{
i_log = log10(*i_ptr)+1;
if ( *i_ptr == 0) i_log = 1;
i_erg = (*i_ptr + (pow ( 10, i_log ) * i_rest ));
outfile<<"("<<i_erg<<")";
i_rest = i_erg%i_divisors;
outfile<<i_rest<<" ";
}
...stuff
Folgende Zahl habe ich durch 3 geteilt:
Code:
4 90 5 9 8 9 30 6 5 50 7 9 2 200 5 100 300 40 4 9 5 500 1 8 90 8 5 9 200 800 300 5 90 20 5 50 50 5 50 300 50 4 400 9 5 90 2 5 4 9 50 7 300 50 7 5 50 100 9 50 4 800 300 2 5 1 3 8 200 5 50 300 40 100 9 5 800 300 5 90 6 1 8 90 5 50 4 5 50 50 5 100 100 200 5 8 200 7 5 100 3 8 90 9 5 2 5 50 9 8 90 500 5 90 4 5 200 40 9 3 8 100 300 3 8 5 50 300 50 4 6 9 50 4 5 50 4 5 50 50 500 5 50 50 9 8 90 40 9 3 8 400 60 50 7 1 50 800 5 40 8 5 90 800 5 50 100 300 3 8 5 50 500 5 90 4 5 200 100 60 500 9 30 30 9 3 8 40 9 3 8 400 60 50 5 300 3 8 6 9 50 4 5 50 30 1 100 100 5 50 300 50 4 500 5 90 4 5 40 300 5 200 9 7 9 100 200 100 9 5 8 5 4 5 40 7 5 2 5 9 3 8 40 5 9 50 5 7 50 1 4 5 100 70 90 9 3 8 200 4 5 90 8 5 90 90 300 50 4 4 5 90 90 300 6 4 5 100 7 5 9 100 200 5 100 1 50 10 5 50 5 4 9 5 9 40 200 60 4 5 100 9 50 4 9 100 200 4 9 5 100 5 90 50 1 8 200 5 300 3 8 800 300 7 60 200 200 100 60 50 1 8 200 5 90 100 9 3 8 800 300 5 300 3 8 300 50 4 4 5 90 1 40 200 1 7 5 500 1 50 4 5 30 200 4 5 90 100 200 60 5 100 100 200 100 9 3 8 50 9 3 8 200 4 5 50 50 5 100 9 100 200 4 1 100 30 9 3 8 200 9 50 9 8 40 100 60 500 1 5 8 30 5 90 5 3 8 200 4 300 40 5 50 100 3 8 4 1 100 9 100 200 4 5 100 200 1 7 5 100 100 200 300 50 4 5 300 50 4 50 9 3 8 200 4 9 5 800 5 9 200 4 5 90 50 1 3 8 200
Hier die Ergebnissausgabe mit debug Ergebnis aus i_erg und dem Rest nach der Division:
[Gerechnet auf Maschiene A]
Code:
divisor 3
(4)1 (190)1 (15)0 (9)0 (8)2 (29)2 (230)2 (26)2 (25)1 (150)0 (7)1 (19)1 (12)0 (200)2 (25)1 (1100)2 (2300)2 (240)0 (4)1 (19)1 (15)0 (500)2 (21)0 (8)2 (290)2 (28)1 (15)0 (9)0 (200)2 (2800)1 (1300)1 (15)0 (90)0 (20)2 (25)1 (150)0 (50)2 (25)1 (150)0 (300)0 (50)2 (24)0 (400)1 (19)1 (15)0 (90)0 (2)2 (25)1 (14)2 (29)2 (250)1 (17)2 (2300)2 (250)1 (17)2 (25)1 (150)0 (100)1 (19)1 (150)0 (4)1 (1800)0 (300)0 (2)2 (25)1 (11)2 (23)2 (28)1 (1200)0 (5)2 (250)1 (1300)1 (140)2 (2100)0 (9)0 (5)2 (2800)1 (1300)1 (15)0 (90)0 (6)0 (1)1 (18)0 (90)0 (5)2 (250)1 (14)2 (25)1 (150)0 (50)2 (25)1 (1100)2 (2100)0 (200)2 (25)1 (18)0 (200)2 (27)0 (5)2 (2100)0 (3)0 (8)2 (290)2 (29)2 (25)1 (12)0 (5)2 (250)1 (19)1 (18)0 (90)0 (500)2 (25)1 (190)1 (14)2 (25)1 (1200)0 (40)1 (19)1 (13)1 (18)0 (100)1 (1300)1 (13)1 (18)0 (5)2 (250)1 (1300)1 (150)0 (4)1 (16)1 (19)1 (150)0 (4)1 (15)0 (50)2 (24)0 (5)2 (250)1 (150)0 (500)2 (25)1 (150)0 (50)2 (29)2 (28)1 (190)1 (140)2 (29)2 (23)2 (28)1 (1400)2 (260)2 (250)1 (17)2 (21)0 (50)2 (2800)1 (15)0 (40)1 (18)0 (5)2 (290)2 (2800)1 (15)0 (50)2 (2100)0 (300)0 (3)0 (8)2 (25)1 (150)0 (500)2 (25)1 (190)1 (14)2 (25)1 (1200)0 (100)1 (160)1 (1500)0 (9)0 (30)0 (30)0 (9)0 (3)0 (8)2 (240)0 (9)0 (3)0 (8)2 (2400)0 (60)0 (50)2 (25)1 (1300)1 (13)1 (18)0 (6)0 (9)0 (50)2 (24)0 (5)2 (250)1 (130)1 (11)2 (2100)0 (100)1 (15)0 (50)2 (2300)2 (250)1 (14)2 (2500)1 (15)0 (90)0 (4)1 (15)0 (40)1 (1300)1 (15)0 (200)2 (29)2 (27)0 (9)0 (100)1 (1200)0 (100)1 (19)1 (15)0 (8)2 (25)1 (14)2 (25)1 (140)2 (27)0 (5)2 (22)1 (15)0 (9)0 (3)0 (8)2 (240)0 (5)2 (29)2 (250)1 (15)0 (7)1 (150)0 (1)1 (14)2 (25)1 (1100)2 (270)0 (90)0 (9)0 (3)0 (8)2 (2200)1 (14)2 (25)1 (190)1 (18)0 (5)2 (290)2 (290)2 (2300)2 (250)1 (14)2 (24)0 (5)2 (290)2 (290)2 (2300)2 (26)2 (24)0 (5)2 (2100)0 (7)1 (15)0 (9)0 (100)1 (1200)0 (5)2 (2100)0 (1)1 (150)0 (10)1 (15)0 (50)2 (25)1 (14)2 (29)2 (25)1 (19)1 (140)2 (2200)1 (160)1 (14)2 (25)1 (1100)2 (29)2 (250)1 (14)2 (29)2 (2100)0 (200)2 (24)0 (9)0 (5)2 (2100)0 (5)2 (290)2 (250)1 (11)2 (28)1 (1200)0 (5)2 (2300)2 (23)2 (28)1 (1800)0 (300)0 (7)1 (160)1 (1200)0 (200)2 (2100)0 (60)0 (50)2 (21)0 (8)2 (2200)1 (15)0 (90)0 (100)1 (19)1 (13)1 (18)0 (800)2 (2300)2 (25)1 (1300)1 (13)1 (18)0 (300)0 (50)2 (24)0 (4)1 (15)0 (90)0 (1)1 (140)2 (2200)1 (11)2 (27)0 (5)2 (2500)1 (11)2 (250)1 (14)2 (25)1 (130)1 (1200)0 (4)1 (15)0 (90)0 (100)1 (1200)0 (60)0 (5)2 (2100)0 (100)1 (1200)0 (100)1 (19)1 (13)1 (18)0 (50)2 (29)2 (23)2 (28)1 (1200)0 (4)1 (15)0 (50)2 (250)1 (15)0 (100)1 (19)1 (1100)2 (2200)1 (14)2 (21)0 (100)1 (130)1 (19)1 (13)1 (18)0 (200)2 (29)2 (250)1 (19)1 (18)0 (40)1 (1100)2 (260)2 (2500)1 (11)2 (25)1 (18)0 (30)0 (5)2 (290)2 (25)1 (13)1 (18)0 (200)2 (24)0 (300)0 (40)1 (15)0 (50)2 (2100)0 (3)0 (8)2 (24)0 (1)1 (1100)2 (29)2 (2100)0 (200)2 (24)0 (5)2 (2100)0 (200)2 (21)0 (7)1 (15)0 (100)1 (1100)2 (2200)1 (1300)1 (150)0 (4)1 (15)0 (300)0 (50)2 (24)0 (50)2 (29)2 (23)2 (28)1 (1200)0 (4)1 (19)1 (15)0 (800)2 (25)1 (19)1 (1200)0 (4)1 (15)0 (90)0 (50)2 (21)0 (3)0 (8)2 (2200)1
[Gerechnet auf Maschiene B]
Hier ist an Stelle 7 mit der Zahl 230 als Teilergebnis 229 angegeben was falsch ist da sollte nach:
Code:
i_log = log10(*i_ptr)+1; *i_ptr = 30
i_erg = (*i_ptr + (pow ( 10, i_log ) * i_rest )); i_rest = 2
dass sollte für i_erg 230 nicht 229 ergeben.
... Warum???
Code:
divisor 3
(4)1 (190)1 (15)0 (9)0 (8)2 (29)2 (229)1 (16)1 (15)0 (50)2 (27)0 (9)0 (2)2 (2200)1 (15)0 (100)1 (1300)1 (140)2 (24)0 (9)0 (5)2 (2500)1 (11)2 (28)1 (190)1 (18)0 (5)2 (29)2 (2200)1 (1800)0 (300)0 (5)2 (290)2 (219)0 (5)2 (249)0 (50)2 (25)1 (150)0 (300)0 (50)2 (24)0 (400)1 (19)1 (15)0 (90)0 (2)2 (25)1 (14)2 (29)2 (249)0 (7)1 (1300)1 (150)0 (7)1 (15)0 (50)2 (2100)0 (9)0 (50)2 (24)0 (800)2 (2300)2 (22)1 (15)0 (1)1 (13)1 (18)0 (200)2 (25)1 (150)0 (300)0 (40)1 (1100)2 (29)2 (25)1 (1800)0 (300)0 (5)2 (290)2 (26)2 (21)0 (8)2 (290)2 (25)1 (150)0 (4)1 (15)0 (50)2 (249)0 (5)2 (2100)0 (100)1 (1200)0 (5)2 (28)1 (1200)0 (7)1 (15)0 (100)1 (13)1 (18)0 (90)0 (9)0 (5)2 (22)1 (15)0 (50)2 (29)2 (28)1 (190)1 (1500)0 (5)2 (290)2 (24)0 (5)2 (2200)1 (140)2 (29)2 (23)2 (28)1 (1100)2 (2300)2 (23)2 (28)1 (15)0 (50)2 (2300)2 (249)0 (4)1 (16)1 (19)1 (150)0 (4)1 (15)0 (50)2 (24)0 (5)2 (249)0 (50)2 (2500)1 (15)0 (50)2 (249)0 (9)0 (8)2 (290)2 (239)2 (29)2 (23)2 (28)1 (1400)2 (260)2 (249)0 (7)1 (11)2 (249)0 (800)2 (25)1 (140)2 (28)1 (15)0 (90)0 (800)2 (25)1 (150)0 (100)1 (1300)1 (13)1 (18)0 (5)2 (249)0 (500)2 (25)1 (190)1 (14)2 (25)1 (1200)0 (100)1 (160)1 (1500)0 (9)0 (30)0 (30)0 (9)0 (3)0 (8)2 (239)2 (29)2 (23)2 (28)1 (1400)2 (260)2 (249)0 (5)2 (2300)2 (23)2 (28)1 (16)1 (19)1 (150)0 (4)1 (15)0 (50)2 (229)1 (11)2 (2100)0 (100)1 (15)0 (50)2 (2300)2 (249)0 (4)1 (1500)0 (5)2 (290)2 (24)0 (5)2 (239)2 (2300)2 (25)1 (1200)0 (9)0 (7)1 (19)1 (1100)2 (2200)1 (1100)2 (29)2 (25)1 (18)0 (5)2 (24)0 (5)2 (239)2 (27)0 (5)2 (22)1 (15)0 (9)0 (3)0 (8)2 (239)2 (25)1 (19)1 (150)0 (5)2 (27)0 (50)2 (21)0 (4)1 (15)0 (100)1 (170)2 (290)2 (29)2 (23)2 (28)1 (1200)0 (4)1 (15)0 (90)0 (8)2 (25)1 (190)1 (190)1 (1300)1 (150)0 (4)1 (14)2 (25)1 (190)1 (190)1 (1300)1 (16)1 (14)2 (25)1 (1100)2 (27)0 (5)2 (29)2 (2100)0 (200)2 (25)1 (1100)2 (21)0 (50)2 (209)2 (25)1 (150)0 (5)2 (24)0 (9)0 (5)2 (29)2 (239)2 (2200)1 (160)1 (14)2 (25)1 (1100)2 (29)2 (249)0 (4)1 (19)1 (1100)2 (2200)1 (14)2 (29)2 (25)1 (1100)2 (25)1 (190)1 (150)0 (1)1 (18)0 (200)2 (25)1 (1300)1 (13)1 (18)0 (800)2 (2300)2 (27)0 (60)0 (200)2 (2200)1 (1100)2 (260)2 (249)0 (1)1 (18)0 (200)2 (25)1 (190)1 (1100)2 (29)2 (23)2 (28)1 (1800)0 (300)0 (5)2 (2300)2 (23)2 (28)1 (1300)1 (150)0 (4)1 (14)2 (25)1 (190)1 (11)2 (239)2 (2200)1 (11)2 (27)0 (5)2 (2500)1 (11)2 (249)0 (4)1 (15)0 (30)0 (200)2 (24)0 (5)2 (290)2 (2100)0 (200)2 (260)2 (25)1 (1100)2 (2100)0 (200)2 (2100)0 (9)0 (3)0 (8)2 (249)0 (9)0 (3)0 (8)2 (2200)1 (14)2 (25)1 (150)0 (50)2 (25)1 (1100)2 (29)2 (2100)0 (200)2 (24)0 (1)1 (1100)2 (229)1 (19)1 (13)1 (18)0 (200)2 (29)2 (249)0 (9)0 (8)2 (239)2 (2100)0 (60)0 (500)2 (21)0 (5)2 (28)1 (130)1 (15)0 (90)0 (5)2 (23)2 (28)1 (1200)0 (4)1 (1300)1 (140)2 (25)1 (150)0 (100)1 (13)1 (18)0 (4)1 (11)2 (2100)0 (9)0 (100)1 (1200)0 (4)1 (15)0 (100)1 (1200)0 (1)1 (17)2 (25)1 (1100)2 (2100)0 (200)2 (2300)2 (249)0 (4)1 (15)0 (300)0 (50)2 (24)0 (50)2 (29)2 (23)2 (28)1 (1200)0 (4)1 (19)1 (15)0 (800)2 (25)1 (19)1 (1200)0 (4)1 (15)0 (90)0 (50)2 (21)0 (3)0 (8)2 (2200)1
Man beachte den Rest von 1, somit also nicht teilbar durch 3!
Der Array hatte 469 Zahlen inne, die 1, 2 oder 3 stellig sind.
Ich hoffe die Erklärung ist verständlich. Vielen Dank für Deine Hilfe...
Es gibt nicht viele die sich die Mühe machen da zweimal drauf zu schauen.
Aber die Sache ist wichtig!
Lesezeichen