Rechnen wie Adam Ries

Diese Seite als pdf-Datei.

Motivation

Im Schuljahr 2009/2010 habe ich wieder eine fünfte Klasse in Mathematik bekommen. Bisher hatte ich immer bei den Grundrechenarten selbst eine Tabelle in LaTeX gesetzt. Aber das musste doch auch automatisch gehen. Wie kann man dies in ein kleines Skript setzen, dass mir alles selbstständig ausgibt? Hierzu habe ich mich mit der Theorie auseinander gesetzt, die ja nun nicht so schwer ist. Schließlich handelt es sich um die Grundrechenarten...

Herausgekommen ist mal wieder ein kleines Perl-Skript, mitdem ich \LaTeX-Code erzeuge für meine gegebene Rechnung.

Die Theorie

Die schriftliche Addition

Die zu addierenden Zahlen werden so untereinander geschrieben, dass entsprechende Stellen untereinander stehen. Man ordnet die Zahlen rechtsbündig.

Nun addiert man nur die letzten Ziffern der Summanden und notiert sich als Zwischenergebnis die letzte Ziffer des Endergebnisses. Ist das Zwischenergebnis mehrstellig, so notiert man sich als Übertrag die weiteren Stellen. Weiter geht es mit zweiten Stelle. Ist ein Übertrag vorhanden, so wird dieser zu den Ziffern der zweiten Stelle hinzuaddiert. Das Zwischenergebnis ist die erste Stelle des Endergebnisses und die zweite Stelle wird erneut als Übertrag notiert.

Man fährt so lange bis links fort, bis die Summanden keine weiteren Stellen besitzen.

Beispiel für die schriftliche Addition

Eine Beispielrechnung ist die folgende:

Die Rechnungen sind der Reihe nach:

Die schriftliche Subtraktion

Die zu subtrahierenden Zahlen werden so unter den Minuenden geschrieben, dass entsprechende Stellen untereinander stehen. Man ordnet die Zahlen rechtsbündig.

Nun addiert man nur die letzten Ziffern der Subtrahenden und merkt sich das Zwischenergebnis die letzte Ziffer des Endergebnisses. Ist das Zwischenergebnis mehrstellig, so notiert man sich als Übertrag die weiteren Stellen. Die Differenz von dem Zwischenergebnis zur ersten Ziffer des Minuenden ist das Endergebnis. Analog verfährt man mit den weiteren Stellen, bis es keine stellen mehr gibt.

Beispiel für die schriftliche Subtraktion

Eine Beispielrechnung ist die folgende:

Die Rechnungen sind der Reihe nach:

Die schriftliche Multiplikation

Die zu multiplizierenden Zahlen werden nebeneinander geschrieben. Der zweite Faktor wird in seine einzelnen Ziffern zerlegt. Man multipliziert den ersten Faktor mit der ersten Ziffer und schreibt dieses Ergebnis unter die erste Ziffer des zweiten Faktors rechtsbündig. Analog verfährt man, bis man alle Ziffern des zweiten Faktors abgearbeitet hat. Zu guter letzt werden alle Ergebnisse miteinander addiert.

Beispiel für die schriftliche Multiplikation

Eine Beispielrechnung ist die folgende:

Die schriftliche Division

Im Folgenden wird nur die Division mit Rest behandelt. Ich führe hier einmal ein Beispiel für den Algorithmus an:

Der Programmcode

Hier führe ich einmal nur die einzelnen Algorithmen auf für die Grundrechenarten. Das komplette Programm kann hier runtergeladen werden.

Die Addition

 addition.pm 
1 my $summe; 2 3 sub setsumme { 4 my ($ergebnis) = @_; 5 $summe = $ergebnis; 6 } 7 8 sub setaddition { 9 my ($summand) = @_; 10 $summe = $summe + $summand; 11 } 12 13 sub getsumme { 14 return $summe; 15 } 16 17 ## Die Summanden werden eingelesen 18 sub addiereneinlesen { 19 my ( $nummer, $summand, $summandexp ) = @_; 20 21 my $stellensummand; 22 23 if ( $summandexp >= 0 ) { 24 $stellensummand = vorkommastellen( $summand * 10**$summandexp ); 25 } 26 else { 27 $stellensummand = vorkommastellen($summand); 28 if ( $stellensummand <= abs($summandexp) ) { 29 $stellensummand = abs($summandexp) + 1; 30 } 31 } 32 setspaltenanzahl( $stellensummand + 1 ); 33 schreibezahlintabelle( $summand, $summandexp, $nummer, $stellensummand ); 34 setaddition( $summand * 10**$summandexp ); 35 setspaltenanzahl( vorkommastellen( getsumme() ) ); 36 } 37 38 ## Die Rechnungen für die Addtiom finden statt 39 40 sub addierenauslesen { 41 my ($anzahlzeilen) = @_; 42 my ( $j, $i, $speicherzahl ); 43 44 for ( $i = 1 ; $i <= $anzahlzeilen ; $i++ ) { 45 for ( $j = 1 ; $j <= getspaltenanzahl() ; $j++ ) { 46 $speicherzahl = zusammensetzen( $i, 1, $j ); 47 } 48 for ( $j = 1 ; $j <= getspaltenanzahl() ; $j++ ) { 49 schreibezelle( "", $i, $j ); 50 } 51 schreibezahlintabelle( $speicherzahl, 0, $i, getspaltenanzahl() ); 52 53 if ( $i > 1 ) { 54 schreibezelle( "\$+\$", $i, 1 ); 55 } 56 } 57 my $uebertrag = 0; 58 my $teilsumme = 0; 59 for ( $i = getspaltenanzahl() ; $i > 0 ; $i-- ) { 60 for ( $j = 1 ; $j <= $anzahlzeilen ; $j++ ) { 61 if ( ( $rechne[$j][$i] eq "" ) 62 || ( $rechne[$j][$i] eq "\$+\$" ) ) 63 { 64 $teilsumme = $teilsumme; 65 66 } 67 else { 68 $teilsumme += $rechne[$j][$i]; 69 } 70 $uebertrag = ( $teilsumme - ( $teilsumme % 10 ) ) / 10; 71 if ( $uebertrag == 0 ) { 72 $rechne[ $anzahlzeilen + 1 ][ $i - 1 ] = ""; 73 } 74 else { 75 $rechne[ $anzahlzeilen + 1 ][ $i - 1 ] = "\\tiny{" . $uebertrag . "}"; 76 } 77 $rechne[ $anzahlzeilen + 2 ][$i] = $teilsumme % 10; 78 } 79 $teilsumme = $uebertrag; 80 } 81 for ( $j = 1 ; $j <= getspaltenanzahl() ; $j++ ) { 82 schreibezelle( "", $anzahlzeilen + 2, $j ); 83 } 84 schreibezahlintabelle( getsumme(), 0, $anzahlzeilen + 2, getspaltenanzahl() ); 85 86 for ( $i = 1 ; $i <= $anzahlzeilen + 1 ; $i++ ) { 87 lesetabellenzeile( $i, getspaltenanzahl() ); 88 } 89 90 ausgabe("\\hline \\hline"); 91 lesetabellenzeile( $anzahlzeilen + 2, getspaltenanzahl() ); 92 }

Die Subtraktion

 subtraktion.pm 
1 my $differenz = 0; 2 3 sub setdifferenz { 4 my ($ergebnis) = @_; 5 $differenz = $ergebnis; 6 } 7 8 sub setsubtraktion { 9 my ($subtrahend) = @_; 10 $differenz = $differenz - $subtrahend; 11 } 12 13 sub getdifferenz { 14 return $differenz; 15 } 16 17 sub subtrahiereneinlesen { 18 my ( $nummer, $summand, $summandexp ) = @_; 19 20 my ($stellensummand); 21 22 if ( $summandexp >= 0 ) { 23 $stellensummand = vorkommastellen( $summand * 10**$summandexp ); 24 } 25 else { 26 $stellensummand = vorkommastellen($summand); 27 if ( $stellensummand <= abs($summandexp) ) { 28 $stellensummand = abs($summandexp) + 1; 29 } 30 } 31 setspaltenanzahl( $stellensummand + 1 ); 32 33 schreibezahlintabelle( $summand, $summandexp, $nummer, $stellensummand ); 34 if ( $nummer > 1 ) { 35 setsubtraktion( $summand * 10**$summandexp ); 36 setaddition( $summand * 10**$summandexp ); 37 38 } 39 else { 40 schreibezahlintabelle( $summand, $summandexp, 0, $stellensummand ); 41 setsumme(0); 42 setdifferenz( $summand * 10**$summandexp ); 43 } 44 setspaltenanzahl( vorkommastellen( getdifferenz() ) ); 45 46 } 47 48 sub subtrahierenauslesen { 49 my ($anzahlzeilen) = @_; 50 my ( $j, $i, $speicherzahl, $uebertrag, $teilsumme, $teildifferenz, $minuend ); 51 52 for ( $i = 0 ; $i <= $anzahlzeilen ; $i++ ) { 53 for ( $j = 1 ; $j <= getspaltenanzahl() ; $j++ ) { 54 $speicherzahl = zusammensetzen( $i, 1, $j ); 55 } 56 for ( $j = 1 ; $j <= getspaltenanzahl() ; $j++ ) { 57 schreibezelle( "", $i, $j ); 58 } 59 schreibezahlintabelle( $speicherzahl, 0, $i, getspaltenanzahl() ); 60 61 if ( $i > 1 ) { 62 schreibezelle( "\$-\$", $i, 1 ); 63 } 64 } 65 for ( $j = 1 ; $j <= getspaltenanzahl() ; $j++ ) { 66 schreibezelle( "", $anzahlzeilen + 2, $j ); 67 } 68 69 for ( $j = 1 ; $j <= getspaltenanzahl() ; $j++ ) { 70 schreibezahlintabelle( 0, 0, $anzahlzeilen + 1, $j ); 71 schreibezahlintabelle( 0, 0, $anzahlzeilen + 3, $j ); 72 schreibezahlintabelle( 0, 0, $anzahlzeilen + 5, $j ); 73 } 74 75 schreibezahlintabelle( getsumme(), 0, $anzahlzeilen + 3, getspaltenanzahl() ); 76 77 schreibezahlintabelle( getdifferenz(), 0, $anzahlzeilen + 4, getspaltenanzahl() ); 78 79 for ( $i = 1 ; $i <= $anzahlzeilen ; $i++ ) { 80 lesetabellenzeile( $i, getspaltenanzahl() ); 81 } 82 83 $uebertrag = $teilsumme = 0; 84 for ( $i = getspaltenanzahl() ; $i > 0 ; $i-- ) { 85 for ( $j = 2 ; $j <= $anzahlzeilen ; $j++ ) { 86 if ( ( $rechne[$j][$i] eq "" ) 87 || ( $rechne[$j][$i] eq "\$-\$" ) ) 88 { 89 $teilsumme = $teilsumme; 90 91 } 92 else { 93 $teilsumme += $rechne[$j][$i]; 94 } 95 96 $uebertrag = ( $teilsumme - ( $teilsumme % 10 ) ) / 10; 97 98 if ( $uebertrag == 0 ) { 99 $rechne[ $anzahlzeilen + 1 ][ $i - 1 ] = 0; 100 } 101 else { 102 $rechne[ $anzahlzeilen + 1 ][ $i - 1 ] = $uebertrag; 103 } 104 105 $rechne[ $anzahlzeilen + 2 ][$i] = $teilsumme % 10; 106 } 107 108 $teilsumme = $uebertrag; 109 } 110 111 $teildifferenz = $minuend = 0; 112 for ( $j = 1 ; $j <= getspaltenanzahl() ; $j++ ) { 113 $minuend = zusammensetzen( 0, 1, $j ); 114 } 115 for ( $j = getspaltenanzahl() ; $j > getspaltenanzahl() - vorkommastellen($minuend) ; $j-- ) { 116 $teildifferenz = $rechne[0][$j] - $rechne[ $anzahlzeilen + 3 ][$j]; 117 if ( $teildifferenz >= 0 ) { 118 $rechne[ $anzahlzeilen + 5 ][ $j - 1 ] = $rechne[ $anzahlzeilen + 1 ][ $j - 1 ] + 0; 119 } 120 else { 121 $rechne[ $anzahlzeilen + 5 ][ $j - 1 ] = $rechne[ $anzahlzeilen + 1 ][ $j - 1 ] + 1; 122 } 123 } 124 125 for ( $j = 1 ; $j <= getspaltenanzahl() ; $j++ ) { 126 if ( $rechne[ $anzahlzeilen + 5 ][$j] == 0 ) { 127 $rechne[ $anzahlzeilen + 5 ][$j] = ""; 128 } 129 else { 130 $rechne[ $anzahlzeilen + 5 ][$j] = "\\tiny{" . $rechne[ $anzahlzeilen + 5 ][$j] . "}"; 131 } 132 } 133 134 lesetabellenzeile( $anzahlzeilen + 5, getspaltenanzahl() ); 135 ausgabe("\\hline \\hline"); 136 lesetabellenzeile( $anzahlzeilen + 4, getspaltenanzahl() ); 137 }

Die Multiplikation

 multiplikation.pm 
1 sub multipliziere { 2 my ( $faktoreins, $faktoreinsexp, $faktorzwei, $faktorzweiexp ) = @_; 3 4 my ( $stellenfaktoreins, $stellenfaktorzwei, $stellengesamt, $ergebnis, 5 $zeilen, $vorzeichenfaktoreins, $vorzeichenfaktorzwei, 6 $stellenergebnis, $faktorzweispeicher ); 7 8 ## Haben die Zahlen ein negatives Vorzeichen? 9 if ( $faktorzwei < 0 ) { 10 $vorzeichenfaktorzwei = 1; 11 } 12 else { 13 $vorzeichenfaktorzwei = 0; 14 } 15 if ( $faktoreins < 0 ) { 16 $vorzeichenfaktoreins = 1; 17 } 18 else { 19 $vorzeichenfaktoreins = 0; 20 } 21 22 $faktoreins = abs($faktoreins); 23 $faktorzweispeicher = $faktorzwei = abs($faktorzwei); 24 25 ## Vor- oder Nachkommastellen? 26 27 if ( $faktoreinsexp >= 0 ) { 28 $stellenfaktoreins = vorkommastellen( $faktoreins * 10**$faktoreinsexp ); 29 } 30 else { 31 $stellenfaktoreins = vorkommastellen($faktoreins); 32 if ( $stellenfaktoreins <= abs($faktoreinsexp) ) { 33 $stellenfaktoreins = abs($faktoreinsexp) + 1; 34 } 35 } 36 if ( $faktorzweiexp >= 0 ) { 37 $stellenfaktorzwei = vorkommastellen( $faktorzwei * 10**$faktorzweiexp ); 38 } 39 else { 40 41 $stellenfaktorzwei = vorkommastellen($faktorzwei); 42 if ( $stellenfaktorzwei <= abs($faktorzweiexp) ) { 43 $stellenfaktorzwei = abs($faktorzweiexp) + 1; 44 } 45 } 46 47 if ( $faktoreinsexp + $faktorzweiexp >= 0 ) { 48 $stellenergebnis = 49 vorkommastellen( $faktorzwei * 10**$faktorzweiexp * $faktoreins * 10**$faktoreinsexp ); 50 } 51 else { 52 $stellenergebnis = vorkommastellen( $faktorzwei * $faktoreins ); 53 } 54 55 $stellengesamt = 56 $stellenfaktoreins + 1 + $stellenfaktorzwei + $vorzeichenfaktoreins + $vorzeichenfaktorzwei; 57 58 ## Die erste Zeile wird geschrieben 59 ## Was ist zu rechnen 60 61 tabellenkopf($stellengesamt); 62 63 if ( $vorzeichenfaktoreins == 1 ) { 64 schreibezelle( "\$-\$", 1, 1 ); 65 } 66 schreibezahlintabelle( $faktoreins, $faktoreinsexp, 1, 67 $stellenfaktoreins + $vorzeichenfaktoreins ); 68 schreibezelle( "\$\\cdot\$", 1, $stellenfaktoreins + 1 + $vorzeichenfaktoreins ); 69 if ( $vorzeichenfaktorzwei == 1 ) { 70 schreibezelle( "\$-\$", 1, 71 $stellenfaktoreins + 1 + $vorzeichenfaktoreins + $vorzeichenfaktorzwei ); 72 } 73 74 schreibezahlintabelle( $faktorzwei, $faktorzweiexp, 1, 75 $stellenfaktoreins + $vorzeichenfaktoreins + 1 + $stellenfaktorzwei + 76 $vorzeichenfaktorzwei ); 77 78 lesetabellenzeile( 1, $stellengesamt ); 79 ausgabe("\\hline"); 80 $zeilen = 1; 81 82 my $wieoftmultipliziere = vorkommastellen($faktorzwei); 83 84 my $i = 1; 85 my $j = 0; 86 for ( $i = 1 + $stellenfaktorzwei ; $i > 1 ; $i-- ) { 87 88 if ( $faktoreinsexp >= 0 ) { 89 $ergebnis = $faktoreins * 10**$faktoreinsexp * ( $faktorzwei % 10 ); 90 } 91 else { 92 $ergebnis = $faktoreins * ( $faktorzwei % 10 ); 93 } 94 95 schreibezahlintabelle( $ergebnis, 0, $i, $stellengesamt - $j ); 96 $faktorzwei = ( $faktorzwei - ( $faktorzwei % 10 ) ) / 10; 97 $j++; 98 $zeilen++; 99 } 100 $faktorzwei = $faktorzweispeicher; 101 102 for ( $i = 2 ; $i <= $stellenfaktorzwei + 1 ; $i++ ) { 103 lesetabellenzeile( $i, $stellengesamt ); 104 } 105 106 schreibezahlintabelle( $faktoreins * $faktorzwei, $faktoreinsexp + 107 $faktorzweiexp, $zeilen + 3, $stellengesamt ); 108 109 ## Der Uebertrag wird bestimmt 110 111 my $uebertrag = 0; 112 my $teilsumme = 0; 113 for ( $i = $stellengesamt ; $i > 0 ; $i-- ) { 114 for ( $j = 2 ; $j <= $zeilen ; $j++ ) { 115 if ( $rechne[$j][$i] eq "" ) { 116 $teilsumme = $teilsumme; 117 } 118 else { 119 $teilsumme += $rechne[$j][$i]; 120 } 121 122 $uebertrag = ( $teilsumme - ( $teilsumme % 10 ) ) / 10; 123 124 if ( $uebertrag == 0 ) { 125 $rechne[ $zeilen + 1 ][ $i - 1 ] = ""; 126 } 127 else { 128 $rechne[ $zeilen + 1 ][ $i - 1 ] = "\\tiny{" . $uebertrag . "}"; 129 } 130 $rechne[ $zeilen + 2 ][$i] = $teilsumme % 10; 131 } 132 $teilsumme = $uebertrag; 133 } 134 135 ## Das Rechenergebnis wird bestimmt 136 lesetabellenzeile( $zeilen + 1, $stellengesamt ); 137 138 schreibezahlintabelle( 139 $faktoreins * $faktorzwei, 140 $faktoreinsexp + $faktorzweiexp, 141 $zeilen + 3, 142 $stellengesamt 143 ); 144 ausgabe("\\hline \\hline"); 145 if ( ( $vorzeichenfaktoreins + $vorzeichenfaktorzwei ) == 1 ) { 146 schreibezelle( "\$-\$", $zeilen + 3, $stellengesamt - ($stellenergebnis) ); 147 } 148 lesetabellenzeile( $zeilen + 3, $stellengesamt ); 149 tabellenfuss(); 150 }

Die Division

 division.pm 
1 sub dividiere { 2 my ( $dividend, $dividendexp, $divisor, $divisorexp ) = @_; 3 4 my ( $stellendividend, $stellendivisor, $stellengesamt, $ergebnis, 5 $zeilen, $vorzeichendividend, $vorzeichendivisor, $stellenergebnis, 6 $ende, $zwischenergebnis, $i, $merkezahl, $differenz, $starte, $rest, 7 $reststellen ); 8 9 if ( $divisorexp < 0 ) { 10 $rest = 11 ( ( $dividend * 10**$dividendexp * 10**( -$divisorexp ) ) % 12 ( $divisor * 10**$divisorexp * 10**( -$divisorexp ) ) ); 13 } 14 else { 15 $rest = ( ( $dividend * 10**$dividendexp ) % ( $divisor * 10**$divisorexp ) ); 16 } 17 if ( $rest != 0 ) { 18 19 $reststellen = vorkommastellen($rest) + 1; 20 21 } 22 else { 23 $reststellen = 0; 24 } 25 26 my @ergebnisvektor = (); 27 for ( $i = 0 ; $i <= 100 ; $i++ ) { 28 $ergebnisvektor[$i] = ""; 29 } 30 31 ## Haben die Zahlen ein negatives Vorzeichen? 32 if ( $divisor < 0 ) { 33 $vorzeichendivisor = 1; 34 } 35 else { 36 $vorzeichendivisor = 0; 37 } 38 if ( $dividend < 0 ) { 39 $vorzeichendividend = 1; 40 } 41 else { 42 $vorzeichendividend = 0; 43 } 44 45 $dividend = abs($dividend); 46 $divisor = abs($divisor); 47 48 ## Vor- oder Nachkommastellen? 49 50 if ( $dividendexp >= 0 ) { 51 $stellendividend = vorkommastellen( $dividend * 10**$dividendexp ); 52 } 53 else { 54 $stellendividend = vorkommastellen($dividend); 55 if ( $stellendividend <= abs($dividendexp) ) { 56 $stellendividend = abs($dividendexp) + 1; 57 } 58 } 59 if ( $divisorexp >= 0 ) { 60 $stellendivisor = vorkommastellen( $divisor * 10**$divisorexp ); 61 } 62 else { 63 $stellendivisor = vorkommastellen($divisor); 64 if ( $stellendivisor <= abs($divisorexp) ) { 65 $stellendivisor = abs($divisorexp) + 1; 66 } 67 } 68 69 if ( $dividendexp - $divisorexp >= 0 ) { 70 $stellenergebnis = 71 vorkommastellen( ( $dividend * 10**$dividendexp ) / ( $divisor * 10**$divisorexp ) ); 72 } 73 else { 74 $stellenergebnis = vorkommastellen( $dividend / $divisor ); 75 if ( $stellenergebnis <= abs( $dividendexp - $divisorexp ) ) { 76 $stellenergebnis = abs( $dividendexp - $divisorexp ) + 1; 77 } 78 } 79 80 $stellengesamt = 81 $stellendividend + 1 + $stellendivisor + $vorzeichendividend + $vorzeichendivisor + 1 + 82 $stellenergebnis + $reststellen; 83 84 ## Der Tabellenkopf wird geschrieben, wie viele Stellen sind vorhanden. 85 86 tabellenkopf($stellengesamt); 87 88 ## Die erste Zeile wird geschrieben 89 ## Was ist zu rechnen 90 91 if ( $vorzeichendividend == 1 ) { 92 schreibezelle( "\$-\$", 1, 1 ); 93 } 94 schreibezahlintabelle( $dividend, $dividendexp, 1, $stellendividend + $vorzeichendividend ); 95 ## fuer Zwischenrechnungen 96 for ( $i = 0 ; $i < 100 ; $i++ ) { 97 schreibezahlintabelle( 0, 0, 0, $i ); 98 } 99 schreibezahlintabelle( $dividend, $dividendexp, 0, $stellendividend + $vorzeichendividend ); 100 schreibezelle( "\$:\$", 1, $stellendividend + 1 + $vorzeichendividend ); 101 if ( $vorzeichendivisor == 1 ) { 102 schreibezelle( "\$-\$", 1, 103 $stellendividend + 1 + $vorzeichendividend + $vorzeichendivisor ); 104 } 105 106 schreibezahlintabelle( $divisor, $divisorexp, 1, 107 $stellendividend + $vorzeichendividend + 1 + $stellendivisor + $vorzeichendivisor ); 108 109 schreibezelle( "\$=\$", 1, 110 $stellendividend + 1 + $vorzeichendividend + $vorzeichendivisor + $stellendivisor + 1 ); 111 112 schreibezahlintabelle( 113 $dividend / $divisor, 114 $dividendexp - $divisorexp, 115 1, $stellengesamt - $reststellen 116 ); 117 118 if ( $rest != 0 ) { 119 schreibezelle( "R", 1, $stellengesamt - ( $reststellen - 1 ) ); 120 schreibezahlintabelle( $rest, 0, 1, $stellengesamt ); 121 } 122 123 $zeilen = 1; 124 125 lesetabellenzeile( 1, $stellengesamt ); 126 127 if ( $dividendexp > 0 ) { 128 $dividend = $dividend * 10**$dividendexp; 129 } 130 131 if ( $divisorexp > 0 ) { 132 $divisor = $divisor * 10**$divisorexp; 133 } 134 135 if ( $divisorexp < 0 ) { 136 $divisor = $divisor * 10**( -$divisorexp ) * 10**($divisorexp); 137 $dividend = $dividend * 10**( -$divisorexp ); 138 } 139 140 for ( $i = 0 ; $i < $stellenergebnis ; $i++ ) { 141 $ergebnisvektor[ $stellenergebnis - $i ] = zusammensetzen( 142 1, 143 $stellengesamt - $reststellen - $i, 144 $stellengesamt - $reststellen - $i 145 ); 146 } 147 $ende = $differenz = $starte = 0; 148 $zeilen++; 149 my $anfang = 1; 150 my $start = 1; 151 for ( $j = 1 ; $j <= $stellengesamt ; $j++ ) { 152 if ( teilersein( zusammensetzen( 0, $anfang, $j ), int( $ergebnisvektor[1] * $divisor ) ) == 153 1 ) 154 { 155 if ( $starte == 0 ) { 156 $merkezahl = zusammensetzen( 0, $anfang, $j ); 157 $starte = 1; 158 $ende = $j; 159 } 160 } 161 } 162 163 for ( $i = 1 ; $i <= $stellenergebnis ; $i++ ) { 164 $zwischenergebnis = int( $ergebnisvektor[$i] * $divisor ); 165 166 if ( $ergebnisvektor[$i] != 0 ) { 167 168 $differenz = $merkezahl - $zwischenergebnis; 169 170 for ( $j = 1 ; $j <= $ende ; $j++ ) { 171 schreibezahlintabelle( 0, 0, 0, $j ); 172 } 173 174 schreibezahlintabelle( $differenz, 0, 0, $ende ); 175 176 if ( $i > 1 ) { 177 schreibezahlintabelle( $merkezahl, 0, $zeilen, $ende ); 178 lesetabellenzeile( $zeilen, $stellengesamt ); 179 $zeilen++; 180 schreibezahlintabelle( $differenz, 0, 0, $ende ); 181 } 182 183 if ( $zwischenergebnis != 0 ) { 184 schreibezahlintabelle( $zwischenergebnis, 0, $zeilen, $ende ); 185 lesetabellenzeile( $zeilen, $stellengesamt ); 186 ausgabe( "\\cline{" . $start . "-" . $ende . "}" ); 187 $zeilen++; 188 schreibezahlintabelle( $differenz, 0, $zeilen, $ende ); 189 } 190 } 191 $ende++; 192 $merkezahl = zusammensetzen( 0, $anfang, $ende ); 193 $starte = 0; 194 for ( $j = 1 ; $j <= $ende ; $j++ ) { 195 196 if ( zusammensetzen( 0, $j, $j ) == 0 ) { 197 if ( $starte == 0 ) { 198 $start = $j + 1; 199 } 200 } 201 else { 202 $starte = 1; 203 } 204 } 205 } 206 $zeilen++; 207 $ende = vorkommastellen($dividend); 208 schreibezahlintabelle( $rest, 0, $zeilen, $ende ); 209 lesetabellenzeile( $zeilen, $stellengesamt ); 210 tabellenfuss(); 211 }

Anwendung des Programms

Das gesamte Skript kann man nun wie folgt nutzen. Man übergibt an adam-ries.pl eine Datei in der die folgenden Befehle enthalten sind.
mul 123,0,193,0
div 829,0,3,0
addiere
12,2
19,2
ende
subtrahiere
4309,0
2956,0
473,0
ende

Dabei ist eine Zahl immer in der Darstellung Zahl,Exponent.

Noch zu verbessern

Bisher funktionieren meine Programme einwandfrei mit ganzen natürlichen Zahlen. Aus Zeitmangel habe ich noch nicht Dezimalzahlen zur Genüge implementiert. Der Ansatz ist bereits vorhanden, dass man eine Zahl als Tupel angibt mit ihrem Exponenten. So ist z.B. 123,34 = (12334; -2). Aber dies wird nicht bei jeder Rechenart berücksichtigt. Bei der Addition und Subtraktion habe ich noch keine Ausrichtung an dem Komma eingebaut. Bei der Multiplikation und Division funktioniert dies bereits mit Dezimalzahlen.

Als weitere Ergänzung ist noch eine Division mit Rest als Dezimalschreibweise gedacht. Bisher wird nur der Rest ausgegeben.

Letzte Änderung: 07.11.2009: 21:14:02 von X. Rendtel