430 likes | 565 Views
Modulare Programmierung. Beispiel. Schreiben Sie ein Programm, das eine Tabelle erzeugt, die für i=1,7,49,...<1000000000 die Werte i, sqrt(i) und ( double)i*i enthält. i | sqrt(i) | i*i -------------+---------------------+--------------------
E N D
Modulare Programmierung DVG1 - Modulare Programmierung
Beispiel Schreiben Sie ein Programm, das eine Tabelle erzeugt, die für i=1,7,49,...<1000000000 die Werte i, sqrt(i) und (double)i*i enthält. i | sqrt(i) | i*i -------------+---------------------+-------------------- 1 | 1.000000000000E+00 | 1.000000000000E+00 7 | 2.645751311064E+00 | 4.900000000000E+01 49 | 7.000000000000E+00 | 2.401000000000E+03 343 | 1.852025917745E+01 | 1.176490000000E+05 2401 | 4.900000000000E+01 | 5.764801000000E+06 16807 | 1.296418142421E+02 | 2.824752490000E+08 117649 | 3.430000000000E+02 | 1.384128720100E+10 823543 | 9.074926996951E+02 | 6.782230728490E+11 5764801 | 2.401000000000E+03 | 3.323293056960E+13 40353607 | 6.352448897866E+03 | 1.628413597910E+15 282475249 | 1.680700000000E+04 | 7.979226629761E+16 DVG1 - Modulare Programmierung
0.te Näherung public class t1 { public static void main(String [] args) { System.out.println( "\n i | sqrt(i) | i*i"); System.out.println( "-------------+---------------------+--------------------"); for (long i=1;i<1000000000;i*=7) System.out.println(i+" | "+Math.sqrt(i)+" | "+(double)i*i); } } DVG1 - Modulare Programmierung
Ergebnis der 0.ten Näherung i | sqrt(i) | i*i -------------+---------------------+-------------------- 1 | 1.0 | 1.0 7 | 2.6457513110645907 | 49.0 49 | 7.0 | 2401.0 343 | 18.520259177452136 | 117649.0 2401 | 49.0 | 5764801.0 16807 | 129.64181424216494 | 2.82475249E8 117649 | 343.0 | 1.3841287201E10 823543 | 907.4926996951546 | 6.78223072849E11 5764801 | 2401.0 | 3.3232930569601E13 40353607 | 6352.448897866082 | 1.628413597910449E15 282475249 | 16807.0 | 7.9792266297612E16 DVG1 - Modulare Programmierung
1.te Näherung public class t1 { public static void main(String [] args) { System.out.println( "\n i | sqrt(i) | i*i"); System.out.println( "-------------+---------------------+--------------------"); for (long i=1;i<1000000000;i*=7) System.out.println(i+"\t| "+Math.sqrt(i)+"\t| "+(double)i*i); } } DVG1 - Modulare Programmierung
Ergebnis der 1.ten Näherung i | sqrt(i) | i*i -------------+---------------------+-------------------- 1 | 1.0 | 1.0 7 | 2.6457513110645907 | 49.0 49 | 7.0 | 2401.0 343 | 18.520259177452136 | 117649.0 2401 | 49.0 | 5764801.0 16807 | 129.64181424216494 | 2.82475249E8 117649 | 343.0 | 1.3841287201E10 823543 | 907.4926996951546 | 6.78223072849E11 5764801 | 2401.0 | 3.3232930569601E13 40353607 | 6352.448897866082 | 1.628413597910449E15 282475249 | 16807.0 | 7.9792266297612E16 DVG1 - Modulare Programmierung
Probleme • Die Wirkung von Tabulatoren ist nicht vollständig durch das Programm beeinflußbar. • Zahlen sollten rechtsbündig ausgegeben werden. • Das Format von Gleitkommazahlen hängt sehr von dem Wert ab und ist somit nicht vorhersehbar. • Anzahl der Stellen • Exponentialdarstellung • Vorzeichen • Fazit: formatgesteuerte Ausgabe fehlt in JAVA! • Z.B. Pascal: write(i:8,x:8:2); DVG1 - Modulare Programmierung
Formatierung von Festkommazahlen • Eingabe: Festkommazahl (byte, short, int, long) • Alle Festkommatypen werden automatisch nach long konvertiert. ==> Wir wählen long als Eingabetyp: long z • Ausgabe: Zeichenkette, die den Wert der Eingabezahl repräsentiert. • Format der Ausgabe: <bl>...< bl><vz><zn>...<z0> • <bl>: Leerzeichen • <vz>: Vorzeichen = ' ' oder '-' • <zi>: Ziffern • zusätzliche Eingabe: • Länge der Ausgabe: intl DVG1 - Modulare Programmierung
Probleme: • Was tun, wenn falsche Parameter eingegeben werden? ==> einzige Möglichkeit für Fehler ist l<=0 ==> null ausgeben • Was tun, wenn sich die Zahl nicht mit l Stellen darstellen läßt? z.B.: l=3 und z=-12345 ==> Zeichenkette "**...*" mit l Sternen ausgeben DVG1 - Modulare Programmierung
Vorhandene Lösungen untersuchen • In JAVA existiert die Methode Long.toString Aus der JAVA-Doku: • public static String toString(long i) • Returns a new String object representing the specified integer. The argument is converted to signed decimal representation and returned as a string, exactly as if the argument and the radix 10 were given as arguments to the toStringmethod that takes two arguments. • Parameters: • i - along to be converted. • Returns: • a string representation of the argument in base 10. DVG1 - Modulare Programmierung
public static String toString(long i, • int radix) • Creates a string representation of the first argument in the radix specified by the second argument. • ... • If the first argument is negative, the first element of the result is the ASCII minus sign '-' ('\u002d'. If the first argument is not negative, no sign character appears in the result. • The remaining characters of the result represent the magnitude of the first argument. If the magnitude is zero, it is represented by a single zero character '0' ('\u0030'); otherwise, the first character of the representation of the magnitude will not be the zero character. • ... • Parameters: • i - a long. • radix - the radix. • Returns: • a string representation of the argument in the specified radix. DVG1 - Modulare Programmierung
Darstellung ist o.k. • Wenn die Zahl zu klein ist, werden zu wenig Stellen ausgegeben. • Wenn Zahl zu groß ist, werden zu viel Stellen ausgegeben. ==> • Long.toString kann verwendet werden. Das Resultat muß aber modifiziert werden. DVG1 - Modulare Programmierung
true l <= 0 return null; false String s; Berechnung der Ausgabe return s; Blockdiagramm - 1.Version long z, int l DVG1 - Modulare Programmierung
Methode - 1.Version public static String toString (long z, int l) { if ( l <= 0 ) return null; String s; // Berechnung der Ausgabezeichenkette return s; } DVG1 - Modulare Programmierung
true l <= 0 return null; false <l >l s.length() links auffüllen =l Fehlerbehandlung return s; Blockdiagramm - 2.Version long z, int l String s = Long.toString(z); DVG1 - Modulare Programmierung
Methode - 2.Version public static String toString (long z, int l) { if ( l <= 0 ) return null; String s = Long.toString(z); if ( s.length() == l ) return s; if ( s.length() < l) { // links auffuellen return s; } // Fehlerbehandlung return s; } DVG1 - Modulare Programmierung
long z, int l true l <= 0 return null; false String s = Long.toString(z); <l >l s.length() =l false s.length()<l true s.length()<l true s='*'+s; false return s; Blockdiagramm - 3.Version s="*"; s=' '+s; DVG1 - Modulare Programmierung
Methode - 3.Version public static String toString (long z, int l) { if ( l <= 0 ) return null; String s = Long.toString(z); if ( s.length() == l ) return s; if ( s.length() < l) { do { s = ' '+s; } while ( s.length()<l); return s; } s = "*"; while ( s.length() < l) { s = '*' + s; } return s; } DVG1 - Modulare Programmierung
Methode - 1.optimierte Version public static String toString (long z, int l) { if ( l <= 0 ) return null; String s = Long.toString(z); while ( s.length() < l) { s = ' '+s; } if ( s.length() == l ) return s; s = "*"; while ( s.length() < l) { s = '*' + s; } return s; } DVG1 - Modulare Programmierung
Methode - 2.optimierte Version public static String toString (long z, int l) { if ( l <= 0 ) return null; String s = Long.toString(z); char fz = ' '; if ( s.length() > l) { fz= '*' ; s = "*"; } while ( s.length() < l) { s = fz+s; } return s; } DVG1 - Modulare Programmierung
Methode - endgültige Version /** * <EM>toString</EM> konvertiert eine <CODE>long</CODE>-Variable * in eine Zeichenkette und füllt mit Leerzeichen bis zur * Länge <CODE>l</CODE> auf. Die Gesamtlänge enthält * das Vorzeichen "-" für negative Zahlen. <BR> * Falls die Zahl nicht in dem Format darstellbar ist, * wird die Zeichenkette "**...*" ausgegeben. <BR> * Wird <CODE>l<=0</CODE> angegeben, so wird <CODE>null</CODE> * zurückgegeben. * @author Gerhard Telschow * @version 1.0 * @param z auszugebende Variable * @param l Länge der Ausgabe * @return Zeichenkette */ DVG1 - Modulare Programmierung
public static String toString(long z, int l) { // Falls l<= null zurueckgeben ! if (l<=0) return null; // Rohkonvertierung vom System uebernehmen String s = Long.toString(z); // Standardfuellzeichen ist das Leerzeichen char fz = ' '; // Wenn Laenge zu gross ist, Fuellzeichen wird *, // Zeichenkette wird geloescht if ( s.length() > l ) { fz = '*'; s = "*"; } // Wenn noetig mit Fuellzeichen auffuellen while ( s.length() < l) { s = fz + s; } return s; } DVG1 - Modulare Programmierung
2.te Näherung public class t1 { public static void main(String [] args) { System.out.println( "\n i | sqrt(i) | i*i"); System.out.println( "-------------+---------------------+--------------------"); for (long i=1;i<1000000000;i*=7) System.out.println(InOut.toString(i,12)+" | "+Math.sqrt(i)+"\t| "+(double)i*i); } } DVG1 - Modulare Programmierung
Ergebnis der 2.ten Näherung i | sqrt(i) | i*i -------------+---------------------+-------------------- 1 | 1.0 | 1.0 7 | 2.6457513110645907 | 49.0 49 | 7.0 | 2401.0 343 | 18.520259177452136 | 117649.0 2401 | 49.0 | 5764801.0 16807 | 129.64181424216494 | 2.82475249E8 117649 | 343.0 | 1.3841287201E10 823543 | 907.4926996951546 | 6.78223072849E11 5764801 | 2401.0 | 3.3232930569601E13 40353607 | 6352.448897866082 | 1.628413597910449E15 282475249 | 16807.0 | 7.9792266297612E16 DVG1 - Modulare Programmierung
Nutzung der Entwicklung Um die entwickelte Methode weiter zu nutzen und deren Anwendung zu erleichtern, können wir zusätzliche Schnittstellen entwickeln. Z.B.: Konvertierung einer Zahl und anschließende Ausgabe: /** * <EM>print</EM> gibt eine <CODE>long</CODE>-Variable aus und * füllt mit führenden Leerzeichen bis zur Länge * <CODE>l</CODE> auf. Die Gesamtlänge enthält das * Vorzeichen "-" für negative Zahlen.<BR> * Falls die Zahl nicht in dem Format darstellbar ist, wird die * Zeichenkette "**...*" ausgegeben.<BR> * Wird <CODE>l<=0</CODE> angegeben, so erfolgt keine Ausgabe. * @author Gerhard Telschow * @version 1.0 * @param z auszugebende Variable * @param l Länge der Ausgabe incl. Vorzeichen * @return Nothing */ public static void print(long z, int l) { String s = toString(z, l); if ( s != null) System.out.print(s); } DVG1 - Modulare Programmierung
Z.B.: Konvertierung einer Zahl und anschließende Ausgabe mit Zeilenschaltung: /** * <EM>println</EM> gibt eine <CODE>long</CODE>-Variable aus und * füllt mit führenden Leerzeichen bis zur Länge * <CODE>l</CODE> auf. Die Gesamtlänge enthält das * Vorzeichen "-" für negative Zahlen. Anschließend wird * auf eine neue Zeile geschaltet.<BR> * Falls die Zahl nicht in dem Format darstellbar ist, wird die * Zeichenkette "**...*" ausgegeben.<BR> * Wird <CODE>l<=0</CODE> angegeben, so erfolgt keine Ausgabe. * @author Gerhard Telschow * @version 1.0 * @param z auszugebende Variable * @param l Länge der Ausgabe incl. Vorzeichen * @return Nothing */ public static void println(long z, int l) { print(z,l); System.out.println(); } DVG1 - Modulare Programmierung
Grobkonzept Verfeinerung Lösung Optimierung Ausbau Dokumentation Endgültige Lösung Aufgabe Weg von der Aufgabe zur Lösung DVG1 - Modulare Programmierung
Formatierung von Gleitkommazahlen • Eingabe : Gleitkommazahl (float, double) • float wird automatisch nach double konvertiert ==> wählen double : double z • Ausgabe: Zeichenkette, die den Wert der Eingabezahl repräsentiert. • Format der Ausgabe: <vm><m0><.><m1>...<mn>E<ve><ek>...<e0> • <vm>: Vorzeichen = ' ' oder '-' • <mi>: Ziffern der Mantisse mit folgenden Nullen • <ve>: Vorzeichen = '+' oder '-' • <ei>: Ziffern des Exponenten mit führenden Nullen • zusätzliche Eingabe: • Länge der Mantisse: intmant (Stellen nach dem Dezimalpunkt) • Länge des Exponenten: intexpo • Gesamtlänge der Ausgabe: intl , l = mant+expo+5 DVG1 - Modulare Programmierung
Probleme: • Welche Parameter wählt man. Nur zwei der drei Parameter l, mant und expo können genutzt werden. Wählen l und mant. • Was tun, wenn falsche Parameter eingegeben werden? • Fehler ist l < mant+6 • Fehler ist mant < 1 • null ausgeben • Sonderfälle: • z==+0.0 ==> " 0.0...0E+0..0" • z==-0.0 ==> "-0.0...0E+0..0" • z==+Infinity ==> " Inf " • z==-Infinity ==> "-Inf " • z==NaN ==> "NaN " • Was tun, wenn sich die Zahl nicht mit l Stellen darstellen läßt? ==> Zeichenkette "**...*" mit l Sternen ausgeben DVG1 - Modulare Programmierung
Tests für die Sonderfälle • z==+0.0: if ( z == 0.0 & 1.0/z > 0.0 ) ... • z==-0.0: if ( z == 0.0 & 1.0/z < 0.0 ) ... • z==+Infinity: if ( (1.0/z) == 0.0 & z > 0.0 ) ... • z==-Infinity: if ( (1.0/z) == 0.0 & z < 0.0 ) ... • z==NaN: if ( z != z) ... DVG1 - Modulare Programmierung
true l<mant+6 | mant<1 return null; false String s; Sonderfälle Berechnung der Ausgabe return s; Blockdiagramm - 1.Version double z, int l, int mant DVG1 - Modulare Programmierung
Methode - 1.Version public static String toString (double z, int l, int mant) { if ( l < mant+6 | mant < 1 ) return null; String s; // Sonderfaelle // Berechnung der Ausgabezeichenkette return s; } DVG1 - Modulare Programmierung
true z != z s="NaN" false true true 1.0/z==0.0 z>0.0 s=" Inf" false false s="-Inf" true true z==0.0 1.0/z>0.0 s=" 0.0" false false s="-0.0" Mantisse false s.length()>0 Exponent s=s+"E+0" true rechts auffüllen return s; DVG1 - Modulare Programmierung
Methode - Sonderfälle if ( z != z ) s="NaN" ; else { if (1.0/z == 0.0) { if ( z>0.0 ) s=" Inf"; else s="-Inf"; } else { if ( z == 0.0 ) { if ( 1.0/z > 0.0 ) s=" 0.0"; else s="-0.0"; while (s.length()<mant+3) s=s+"0"; s=s+"E+"; while (s.length()<l) s=s+"0"; } } } DVG1 - Modulare Programmierung
if ( s.length() > 0 ) { while (s.length()<l) s=s+" "; return s; } DVG1 - Modulare Programmierung
Vorzeichen bestimmen Mantisse und Exponent berechnen Mantisse umwandeln Vorzeichen des Exponent bestimmen Exponent umwandeln Fehler behandeln Ergebnis berechnen DVG1 - Modulare Programmierung
char vz=' '; true z<0.0 vz='-'; z=-z; false int e=0; true z>=10.0 z*=0.1; e++; false true z<1.0 z*=10.0; e--; false s=Double.toString(z); true s.length()<mant+2 s=s+'0'; false s=s.substring(0,mant+2); DVG1 - Modulare Programmierung
char vze='+'; true e<0 vze='-'; e=-e; false String se=Integer.toString(e); true se.length()<l-mant-5 se='0'+se; false true se.length()>l-mant-5 s.length()<l s=""; false s=s+'*'; return s; return vz+s+'E'+vze+se; false true DVG1 - Modulare Programmierung
/**********************************************************************/********************************************************************** Das Vorzeichen wird bestimmt, in vz gemerkt und die Zahl in positiv verwandelt. ***********************************************************************/ char vz = ' '; if (z<0.0) { vz='-'; z=-z; } /********************************************************************** Der Exponent wird berechnet; z*10^e bleibt der eingegebene Wert ***********************************************************************/ int e = 0; while (z >= 10.0) { z*=0.1; e++; } while (z<1.0) { z*=10.0; e--; } /********************************************************************** Mantisse umwandeln **********************************************************************/ s=Double.toString(z); while (s.length()<mant+2) s=s+'0'; s=s.substring(0,mant+2); DVG1 - Modulare Programmierung
/**********************************************************************/********************************************************************** Vorzeichen des Exponenten bestimmen **********************************************************************/ String vze = "+"; if (e<0) { vze="-"; e=-e; } /********************************************************************** Exponenten umwandeln **********************************************************************/ String se = Integer.toString(e); while (se.length()<l-mant-5) se="0"+se; if ( se.length()>l-mant-5) { s=""; while (s.length()<l) s=s+'*'; return s; } /********************************************************************** Ergebnis zusammenfuegen **********************************************************************/ return vz+s+'E'+vze+se; DVG1 - Modulare Programmierung
3.te Näherung public class t1 { public static void main(String [] args) { System.out.println( "\n i | sqrt(i) | i*i"); System.out.println( "-------------+---------------------+--------------------"); for (long i=1;i<1000000000;i*=7) System.out.println(InOut.toString(i,12)+" | "+ InOut.toString(Math.sqrt(i),19,12)+" | "+ InOut.toString((double)i*i),19,12)); } } DVG1 - Modulare Programmierung
Ergebnis der 3.ten Näherung i | sqrt(i) | i*i -------------+---------------------+-------------------- 1 | 1.000000000000E+00 | 1.000000000000E+00 7 | 2.645751311064E+00 | 4.900000000000E+01 49 | 7.000000000000E+00 | 2.401000000000E+03 343 | 1.852025917745E+01 | 1.176490000000E+05 2401 | 4.900000000000E+01 | 5.764801000000E+06 16807 | 1.296418142421E+02 | 2.824752490000E+08 117649 | 3.430000000000E+02 | 1.384128720100E+10 823543 | 9.074926996951E+02 | 6.782230728490E+11 5764801 | 2.401000000000E+03 | 3.323293056960E+13 40353607 | 6.352448897866E+03 | 1.628413597910E+15 282475249 | 1.680700000000E+04 | 7.979226629761E+16 DVG1 - Modulare Programmierung
Nutzung der Entwicklung Um die entwickelte Methode weiter zu nutzen und deren Anwendung zu erleichtern, können wir zusätzliche Schnittstellen entwickeln. Z.B.: Konvertierung einer Zahl und anschließende Ausgabe: public static void print(double z, int l, int mant) { String s = toString(z, l, mant); if ( s != null) System.out.print(s); } public static void println(double z, int l, int mant) { print(z, l, mant); System.out.println(); } DVG1 - Modulare Programmierung