Java Rechner Programmierung der Mathematik

HerrInfo

Aktives Mitglied
Hallo zusammen,

ich bin in Moment dabei einen Rechner in Java mit GUI zu programmieren. Leider stehe ich gerade auf dem Schlauch, wie ich es schaffen kann, unendlich viele Zahlen miteinander zu verrechnen. Ich hoffe, es kann mir jemand dabei helfen. Hier seht ihr noch, was ich bisher schon programmiert habe. Vielen Dank schonmal im Voraus.

Meine Main Klasse:
Java:
import java.util.Arrays;

public class Main {
    static double[] zahlen = new double[200];
    static double[] zahlen2 = new double[200];
    static char[] rechenzeichen = new char[100];
    static double ergebnis;
    public static void main(String[] args)
    {
        int zähler = 0;
        MyFrame frame = new MyFrame();
        Arrays.fill(zahlen, 0);
        Arrays.fill(rechenzeichen,'x');



        while (true) {

            if (frame.zwischenrechenzeichen.equals("=")) {
                System.out.println(ergebnis);
            }
            else if (frame.zwischenrechenzeichen.equals("+")) {
                zahlen[zähler] = Double.parseDouble(frame.zwischenzahl);
                rechenzeichen[zähler] = '+';
                zähler++;
            } else if (frame.zwischenrechenzeichen.equals("-")) {
                zahlen[zähler] = Double.parseDouble(frame.zwischenzahl);
                rechenzeichen[zähler] = '-';
                zähler++;
            } else if (frame.zwischenrechenzeichen.equals("x")) {
                zahlen[zähler] = Double.parseDouble(frame.zwischenzahl);
                rechenzeichen[zähler] = 'x';
                zähler++;
            }else if (frame.zwischenrechenzeichen.equals("/")) {
                zahlen[zähler] = Double.parseDouble(frame.zwischenzahl);
                rechenzeichen[zähler] = '/';
                zähler++;
            }

            for (int i = 0; i < rechenzeichen.length; i++) {
                zahlen2 = zahlen.clone();
                if (rechenzeichen[i] == 'x' || rechenzeichen[i] == '/')
                {
                    if (rechenzeichen[i] == 'x'){
                        zahlen[i-1] = 0;
                        zahlen2[i] = zahlen  [i-1] * zahlen[i];
                    } else if (rechenzeichen[i] == '/') {
                        zahlen[i-1] = 0;
                        zahlen2[i] = zahlen  [i-1] / zahlen[i];
                    }
                }
            }





        }
    }
}

Und meine MyFrame Klasse
Code:
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MyFrame extends JFrame
{
    String[] zahlen = new String[100];
    String zwischenzahl=new String("");
    List<String> listezahlen = new ArrayList<String>();
    Character zwischenrechenzeichen;
    JLabel rechnunglabel;
    String rechnung;
    JPanel rechnunghintergrund;
    JButton[] Buttonnumbers = new JButton[10];
    JButton kommerta = new JButton();
    JButton plusminus = new JButton();
    JButton plus = new JButton();
    JButton minus = new JButton();
    JButton mal = new JButton();
    JButton geteilt = new JButton();
    JButton gleich = new JButton();


    MyFrame()
    {
        this.setTitle("Rechner");
        this.setSize(400, 600);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ImageIcon image = new ImageIcon("D://Java//IntelliJ IDEA Community Edition 2022.2.1//Projekts//Rechner//src//Rechner_logo.png");
        this.setIconImage(image.getImage());
        this.getContentPane().setBackground(new Color(0x123456));
        this.setResizable(true);
        this.setLayout(null);

        Arrays.fill(this.zahlen, new String("0"));
        zwischenrechenzeichen = 'z';
        

        rechnunghintergrund = new JPanel();
        rechnunghintergrund.setBounds(0,0,400,125);
        rechnunghintergrund.setBackground(new Color(0x02164E));

        rechnunglabel = new JLabel();
        rechnunglabel.setText("");
        

        for (int i = 0; i < Buttonnumbers.length; i++) {
            Buttonnumbers[i] = new JButton();
            Buttonnumbers[i].setText(String.valueOf(i));
            Buttonnumbers[i].setFont(new Font("Comic Sans", Font.BOLD, 30));
            Buttonnumbers[i].setFocusable(false);
            this.add(Buttonnumbers[i]);
        }
        Buttonnumbers[0].setBounds(110,500,70,50);
        Buttonnumbers[1].setBounds(10,425,70,50);
        Buttonnumbers[2].setBounds(110,425,70,50);
        Buttonnumbers[3].setBounds(210,425,70,50);
        Buttonnumbers[4].setBounds(10,350,70,50);
        Buttonnumbers[5].setBounds(110,350,70,50);
        Buttonnumbers[6].setBounds(210,350,70,50);
        Buttonnumbers[7].setBounds(10,275,70,50);
        Buttonnumbers[8].setBounds(110,275,70,50);
        Buttonnumbers[9].setBounds(210,275,70,50);

        Buttonnumbers[0].addActionListener(e -> {
            listezahlen.add("0");
            
        });
        Buttonnumbers[1].addActionListener(e -> {
            listezahlen.add("1");
        });
        Buttonnumbers[2].addActionListener(e -> {
            listezahlen.add("2");
        });
        Buttonnumbers[3].addActionListener(e -> {
            listezahlen.add("3");
        });
        Buttonnumbers[4].addActionListener(e -> {
            listezahlen.add("4");
        });
        Buttonnumbers[5].addActionListener(e -> {
            listezahlen.add("5");
        });
        Buttonnumbers[6].addActionListener(e -> {
            listezahlen.add("6");
        });
        Buttonnumbers[7].addActionListener(e -> {
            listezahlen.add("7");
        });
        Buttonnumbers[8].addActionListener(e -> {
            listezahlen.add("8");
        });
        Buttonnumbers[9].addActionListener(e -> {
            listezahlen.add("9");
        });

        kommerta.setText(",");
        kommerta.setFont(new Font("Comic Sans", Font.BOLD, 30));
        kommerta.setFocusable(false);
        kommerta.setBounds(210,500,70,50);
        kommerta.addActionListener(e -> {
            listezahlen.add(".");
        });
        this.add(kommerta);

        plusminus.setText("+/-");
        plusminus.setFocusable(false);
        plusminus.setBounds(10,500,70,50);
        plusminus.addActionListener(e -> {
            zwischenzahl = String.join(listezahlen.toString());
            listezahlen.clear();
            zwischenrechenzeichen = '-';
        });
        this.add(plusminus);

        plus.setText("+");
        plus.setFont(new Font("Comic Sans", Font.BOLD, 30));
        plus.setFocusable(false);
        plus.setBounds(310,425,70,50);
        plus.addActionListener(e -> {
            zwischenzahl = String.join(listezahlen.toString());
            listezahlen.clear();
            zwischenrechenzeichen = '+';
        });
        this.add(plus);

        minus.setText("-");
        minus.setFont(new Font("Comic Sans", Font.BOLD, 30));
        minus.setFocusable(false);
        minus.setBounds(310,350,70,50);
        minus.addActionListener(e -> {
            zwischenzahl = String.join(listezahlen.toString());
            listezahlen.clear();
            zwischenrechenzeichen = '-';
        });
        this.add(minus);

        mal.setText("x");
        mal.setFont(new Font("Comic Sans", Font.BOLD, 30));
        mal.setFocusable(false);
        mal.setBounds(310,275,70,50);
        mal.addActionListener(e -> {
            zwischenzahl = String.join(listezahlen.toString());
            listezahlen.clear();
            zwischenrechenzeichen = 'x';
        });
        this.add(mal);

        geteilt.setText("/");
        geteilt.setFont(new Font("Comic Sans", Font.BOLD, 30));
        geteilt.setFocusable(false);
        geteilt.setBounds(310,200,70,50);
        geteilt.addActionListener(e -> {
            zwischenzahl = String.join(listezahlen.toString());
            zwischenrechenzeichen = '/';
        });
        this.add(geteilt);

        gleich.setText("=");
        gleich.setFont(new Font("Comic Sans", Font.BOLD, 30));
        gleich.setFocusable(false);
        gleich.setBounds(310,500,70,50);
        gleich.addActionListener(e -> {
            zwischenzahl = String.join(listezahlen.toString());
            listezahlen.clear();
            for (JButton number : Buttonnumbers) {
                number.setEnabled(false);
            }
            kommerta.setEnabled(false);
            plusminus.setEnabled(false);
            plus.setEnabled(false);
            minus.setEnabled(false);
            mal.setEnabled(false);
            geteilt.setEnabled(false);
            gleich.setEnabled(false);
        });

        this.add(gleich);



        //this.setExtendedState(MAXIMIZED_BOTH); Fullscreen



        rechnunglabel.setBounds(100,50,1000,25);
        rechnunglabel.setFont(new Font("Comic Sans", Font.BOLD, 20));
        rechnunglabel.setForeground(Color.WHITE);
        //rechnunglabel.setText("");
        this.add(rechnunglabel);
        this.add(rechnunghintergrund);
        this.setVisible(true);
    }

}
 
in Java mit GUI zu programmieren.
Fehler #1. Die GUI ist das, was am wenigsten interessiert.

ich bin in Moment dabei einen Rechner in Java
Fehler #2. Du suchst nach einem Algorithmus, da stört die Programmiersprache eher, denn das:
wie ich es schaffen kann, unendlich viele Zahlen miteinander zu verrechnen
kann man sich ganz ohne Computer überlegen.

Fangen wir einmal mittendrin an: Du hast irgendein Zwischenergebnis, nennen wir das mal e, außerdem hast Du einen binären Operator op. Dann tippst Du eine Zahl z ein (d. h. Ziffer für Ziffer), dann einen weiteren Operator op1.

Was passiert?
  1. Der zweite Operator op1 schließt die Eingabe der Ziffernfolge ab, so dass sich aus dieser die Zahl z ergibt.
  2. Mit Abschluss der Zahl z sind die Operanden des vorangegangenen Operators vollständig und das neue Ergebnis kann berechnet werden, indem der Operator op auf das Zwischenergebnis e und die Zahl z angewendet wird.
Links vom Operator steht also immer das bisherige Zwischenergebnis, rechts davon die eingegebene Zahl. Das funktioniert, so lange man mitten in der Rechnung ist, doch was ist am Anfang? Da müsste man erstmal die Zahl links vom Operator angeben, oder? Nicht unbedingt. Wir können ja von einem Zwischenergebnis 0 und einen Operator "+" ausgehen. Damit ist jede eingegebene Zahl immer der zweite Operand.

Dann kann man sich natürlich noch Feinheiten überlegen: was passiert, wenn ich zuerst ein '+', dann ein '-' eingebe, ohne dazwischen eine Ziffer getippt zu haben? Dann könnte man das als Korrektur verstehen, d. h. der Operator wird einfach geändert.

Den Spaß kann man jetzt umsetzen, ganz ohne UI. Mal ganz auf die Schnelle (Achtung: der Code ist kompakt dargestellt, sollte man ordentlich formatieren), als Starter:

Java:
public class Rechner {
    private double ergebnis = 0d;
    private char operator = '+';
    private StringBuilder operand = new StringBuilder();

    public void ziffernzeichen(char ch) { operand.append(ch); }

    public void operator(char ch) {
        if (!istOperatorKorrektur()) {
            berechneZwischenergebnis();
        }

        operator = ch;
    }

    private void berechneZwischenergebnis() {          
        double zahl = Double.parseDouble(operand.toString());
        operand = new StringBuilder();

        ergebnis = switch (operator) {
            case '+' -> ergebnis + zahl;
            case '-' -> ergebnis - zahl;
            case '*' -> ergebnis * zahl;
            case '/' -> ergebnis / zahl;
            default -> ergebnis;
        };
    }
    
    private boolean istOperatorKorrektur() { return operand.length() == 0; }
    public String gibOperand() { return operand.toString(); }
    public double gibErgebnis() { return ergebnis; }
}

Beispielrechnung "1.5 * 2":
Java:
Rechner r = new Rechner();
r.ziffernzeichen('1');
r.ziffernzeichen('.');
r.ziffernzeichen('5');
r.operator('*');
r.ziffernzeichen('2');
r.operator('=');
System.out.println(r.gibErgebnis());
liefert dann am Ende erwartungsgemäß 3.0.
 
Erst einmal danke für die schnelle Antwort.
Ich habe das ganze jetzt einmal ausprobiert und bin dann auf das Problem der Punkt vor Strich-Rechnung gestoßen. Wie kann ich das dann noch implementieren? Deshalb hatte ich versucht das ganze über Arrays zu lösen, hat aber nicht so geklappt wie gedacht.

Wenn hier jetzt am Anfang + 1 gerechnet wird, kommt nicht wie erwartet 4 raus sondern 5. Die Rechnerklasse habe ich von übernommen

Java:
public class Main {

    public static void main(String[] args)
    {
        Rechner r = new Rechner();
        r.ziffernzeichen('1');
        r.operator('+');
        r.ziffernzeichen('1');
        r.ziffernzeichen('.');
        r.ziffernzeichen('5');
        r.operator('*');
        r.ziffernzeichen('2');
        r.operator('=');
        System.out.println(r.gibErgebnis());
    }
}
 
Ich möchte nur mal darauf hinweisen, dass double ein ganz schlechter Datentyp ist, um einen Rechner zu programmieren. Vor allem dann, wenn mit dem Ergebnis weiter gerechnet werden soll:
Java:
System.out.println("1.07D - 1.06D = " + (1.07D - 1.06D));
Code:
1.07D - 1.06D = 0.010000000000000009
Java:
System.out.println("1.07D - 1.06D = " + new BigDecimal("1.07").subtract(new BigDecimal("1.06")));
Code:
1.07D - 1.06D = 0.01
 
Ich möchte nur mal darauf hinweisen, dass double ein ganz schlechter Datentyp ist, um einen Rechner zu programmieren.
Ich könnte mir vorstellen, dass ein Taschenrechner nichts anderes verwendet.

bin dann auf das Problem der Punkt vor Strich-Rechnung gestoßen.
Das Problem stellt sich bei dieser Art des Rechners nicht, da das Zwischenergebnis sofort berechnet wird - so wie einfache Taschenrechner funktionieren. Bei Eingabe von "1 + 0,5 *" zeigt das Teil erstmal 1,5 an, dann tippt man z. b. noch "2 =" und es kommt 3 raus. Punkt vor Strich muss der Anwender berücksichtigen, er müsste also "0,5 * 2 + 1 =" tippen, wenn er 1 + 0,5*2 berechnen will.

Habe ein Lösung für mein zweites Problem hier gefunden:
Das ist eine ganz andere Geschichte: dort wird ein Ausdruck ausgewertet. Wenn man das vernünftig machen will, erstellt man einen Baum, dessen Knoten Zahlen oder Operatoren sind. Ein binärer Operator hat dann einen linken und einen rechten Knoten, für jeden Knoten kannst Du das Ergebnis abrufen. Code dazu findest Du hier im Forum en masse, vor ein paar Tagen erst habe ich das für logische Ausdrücke reingestellt, @KonradN hat das für "normale" mathematische Ausdrücke in seinem Github-Repo, wenn ich mich recht entsinne.
 
@KonradN hat das für "normale" mathematische Ausdrücke in seinem Github-Repo, wenn ich mich recht entsinne.
Jo, der Code ist direkt unter:

Aber ich bin immer noch nicht dazu gekommen, Unit Tests zu schreiben....
 
Hatte vor einiger Zeit einen Taschenrechner mit double gemacht.
Funktioniert für den Hausgebrauch sehr gut.
Anhang anzeigen 19801
Nein funktioniert nicht:
Java:
java -jar '/home/maik/Downloads/Calculator.jar'
false
7
false
72
false
724
false
724.
false
724.6
false
724.64
false
724.64+
false
724.64+1
false
724.64+10
false
724.64+100
false
724.64+1000
calculate null
true
=
 
sind wohl verschiedene Häuser
@Oneixee5 hat mit seiner Aussage recht. Ich habe eine kleine Mathematische Sprache geschrieben die Schleifen Matrix Vektor Funktionsdefinitionen ... kann.
Da macht BigDecimal durchaus Sinn da in einer Schleife mit der Ungenauigkeit von Double der Fehler stärker kumuliert.
Für einen Rechner wie den von mir zum Testen upgeloadet. Ist auch double brauchbar.
Der Fehler 1.07D - 1.06D = 0.01 tritt dort auch nicht auf da der String auf einen gewisse Anzahl von Stellen formatiert wird.
Er ist aber vorhanden. Stell dir jetzt eine Schleife mit 10000 Durchläufen vor .....
 
Mein Casio zeigt zehn Stellen an und rechnet intern mit 14. Oder so ähnlich...
Das ist durchaus möglich. Jedenfalls wird man immer mit Ungenauigkeiteiten leben müssen, die Frage ist doch nur, in welchen Situationen diese auftreten und wer bzw. was man berechnet.

Die pauschale Aussage, dass double ein schlechter Datentyp zum Rechnen wäre, halte ich daher für ... gewagt. Die ganze Welt rechnet damit und das ganz gut.

Ich kann auch mal ein Gegenbeispiel konstruieren: (1.0 / 3.0) * 3.0 ergibt was? Mit double erhalte ich 1.0. Bei BigDecimal sieht die Sache etwas anders aus: da muss ich bei 1.0 / 3.0 die Genauigkeit angeben, auf die gerundet werden soll, und erhalte entsprechend viele 3er nach der Nkst. Dann multipliziere ich mit 3 und erhalte ebenso viele 9er nach der Nkst. Was ist nun besser? 1.0 oder 0,999999999999...?
 
Jo, der Code ist direkt unter:

Aber ich bin immer noch nicht dazu gekommen, Unit Tests zu schreiben....
du hast einen kleinen typo in deiner exception ist mir beim anschauen aufgefallen


Java:
default -> throw new IllegalStateException("Operaror " + operator + " ist ungültig!");
 
Ich kann auch mal ein Gegenbeispiel konstruieren: (1.0 / 3.0) * 3.0 ergibt was? Mit double erhalte ich 1.0. Bei BigDecimal sieht die Sache etwas anders aus: da muss ich bei 1.0 / 3.0 die Genauigkeit angeben, auf die gerundet werden soll, und erhalte entsprechend viele 3er nach der Nkst. Dann multipliziere ich mit 3 und erhalte ebenso viele 9er nach der Nkst. Was ist nun besser? 1.0 oder 0,999999999999...?
Besser ist natürlich das was richtig ist und 1.0 ist nun mal nicht richtig.
 
google rechner scheint den fall auch mit 1.0 zu beantworten
Ja das ist OK. Wenn man aber das Zwischenergebnis verwendet, also nicht 0,333...Periode sondern auf z.B. 5 Stellen nach dem Komma kürzt, dann erhält man auch nicht 1. Es ist also eine andere Ausgangslage. Ich kenne keinen jetzt keinen Datentyp in Java der out-of-the-box mit periodischer Genauigkeit umgehen könnte. Das betrifft auch double.
 
Die Frage relativiert sich, siehe Ist 0,999... wirklich 1?
Hab es mir jetzt nicht angesehen, aber ich denke, hier gehts um "unendlich viele Stellen nach dem Komma", oder? Das haben wir hier ja nicht.

Ich kenne keinen jetzt keinen Datentyp in Java der out-of-the-box mit periodischer Genauigkeit umgehen könnte. Das betrifft auch double.
Ich auch nicht. Und da kommen wir wieder zurück zur Frage: wer braucht das und in welchen Fällen? Oder andersrum formuliert: es scheint ja kein großer Bedarf zu bestehen, sonst gäbe es einen solchen Typ. Man muss halt gewisse Ungenauigkeiten berücksichtigen.
 
Die Frage ist doch immer, was man genau benötigt. Davon abhängig kann man dann die Datentypen so wählen, wie man es braucht.

Wenn der Umgang mit Perioden wichtig ist, dann kann man doch direkt die Brüche speichern. 1/3 ist damit 1/3.

Ähnliche Aspekte kann man ggf. auch in anderen Bereichen anwenden - Das setzt aber dann einiges an Mathematik voraus. Und die Kmomplexität kann dann sehr hoch werden (z.B. wenn man Potenzen unterstützt.)

Also immer klar eine Frage von dem, was man genau will bzw. braucht.
 
Wer erinnert sich noch an den Windows Taschenrechner, der schon ab der zweiten Kommastelle Fehler gemacht hat?
(und den "skandalösen" Rechenfehler des Pentium 60/90?)

Double-Operationen bieten ca. 13 brauchbare Nachkommastellen, damit kommt man in den meisten Fällen aus.
Außerdem hält einen niemand davon ab, Zwischenergebnisse zu runden, was z.B. bei periodischen Zahlen natürlich wenig Sinn ergibt.
 
Wir haben früher den Windows-Rechner benutzt um Last auf dem System zu simulieren und dann unsere Anwendungen unter Last zu testen. Jeder Windows-Rechner hat immer schön einen Kern auf Vollast genutzt, mit der richtigen Formel.
 
Ich auch nicht. Und da kommen wir wieder zurück zur Frage: wer braucht das und in welchen Fällen? Oder andersrum formuliert: es scheint ja kein großer Bedarf zu bestehen, sonst gäbe es einen solchen Typ. Man muss halt gewisse Ungenauigkeiten berücksichtigen.

Kann es so einen Datentypen überhaupt geben? Wir haben immerhin eine endliche Bitbreite, und soweit ich weiß würde ich sagen, daß es für jedes Stellensystem mindestens eine Zahl gibt, die nicht durch eine endliche Ziffernfolge darstellbar ist (beweisen darf das aber wer anders).
 
Kann es so einen Datentypen überhaupt geben? Wir haben immerhin eine endliche Bitbreite, und soweit ich weiß würde ich sagen, daß es für jedes Stellensystem mindestens eine Zahl gibt, die nicht durch eine endliche Ziffernfolge darstellbar ist (beweisen darf das aber wer anders).
Die Frage ist, was du genau machen willst. Beispiel Brüche: da hast du die Möglichkeit, diese zu behalten und schon ist das Problem mehr oder weniger gelöst.

Datentypen für beliebig große Zahlen haben wir schon.

Bei Potenzen wird es problematischer, aber dann darf man die auch nicht mehr ausrechnen. (Also Wurzeln und so)

Das bringt dann aber noch einmal deutlich komplexere Rechnungen mit sich.

Dann bleiben so Dinge wie pi, e, …. Das bleibt dann als Konstanten ….

Man kann das also sehr weit treiben. Und unter dem Strich machen Mathematiker auch nichts anderes. Da wird dann ja oft ebenso verfahren. Da wird ein Wurzel aus 2 weiter geführt und so.
 
Kann es so einen Datentypen überhaupt geben?
Es ging hier ja nur um das Beispiel periodisch wiederkehrender Nachkommastellen und die kann man - wie auf dem Blatt Papier auch - natürlich exakt darstellen. "Null Komma Periode Drei" kann man z. B. als rationale Zahl als Bruch 1/3 schreiben, da reichen sogar ein paar Bits. Bei irrationalen Zahlen wirds natürlich "schwierig".
 
Ich kenne keinen jetzt keinen Datentyp in Java der out-of-the-box mit periodischer Genauigkeit umgehen könnte. Das betrifft auch double.
Das war einer der 1ten Punkte die in der Vorlesung Numerische Mathematik aufgezeigt wurde.
Es gibt kein Speichermedium und es wird nie ein Speichermedium geben das die Zahl PI bis auf die letzte Kommastelle speichern kann.
Warum? Unendlich viele Kommastellen. Was macht der Computer? Er findet eine möglichst gute Näherung an den gesuchten Wert.
Da gibt es in der Analysis die Reihenentwicklung wie Taylor - Reihe etc., um sich an das gewünschte Ergebnis heranzutasten.
In der Numerik ist ein wichtiger Punkt die Fehlerabschätzung.
Der Punkt ist jeder Datentyp auch BigDecimal muss sich auf eine Genauigkeit festlegen. Das bedeutet es wird bei unendlichen Stellen immer eine Näherung bleiben.
 
Wie @KonradN schon anführte, ist der Trick hier eben nicht, eine Zahl als ihre Stellensystemrepräsentation (dezimal, binär, etc.) zu speichern, sondern z.B. symbolisch bzw. als die diese Zahl generierende Formel bzw. den mathematischen Ausdruck, der eben diese Zahl ergibt.
Ein Beispiel für Zahlen, die sich periodisch wiederholen sind hier ja die ebenfalls schon angeführten ratio-nalen Zahlen, also Zahlen, die sich aus einem einfachen arithmetischen Ausdruck ergeben: Brüchen.

Eine Zahl als ihre Stellenwertdarstellung zu speichern, ist so ziemlich die schlechtestmögliche Variante hinsichtlich Speicherverbrauch, aber eben die beste und universellste Form, um (numerische) Arithmetik auf dieser Zahl auszuführen.

Wenn wir aber Zahlen nicht mehr als ihre Stellenwertdarstellung speichern, sondern "symbolisch", müssen wir dann auch Arithmetik symbolisch durchführen. Und da kommen wir dann in den Bereich von Computeralgebrasystemen (CAS).

Wie aber auch schon aufgeführt wurde, ist die Frage immer: Wie genau brauchen wir es denn? Wenn PI auf 6-7 Nachkommastellen gerundet für den konkreten Anwendungsfall ausreicht, dann ist ja alles okay und wir können PI als seine Binärdarstellung (z.B: als Fließkommazahl mit double) oder Dezimaldarstellung (z.B. als BigDecimal) speichern.
 
wie ich es schaffen kann, unendlich viele Zahlen miteinander zu verrechnen.
Ich sehe immer noch dieses Zitat als Aufgabe an. Dies impliziert die größtmögliche Genauigkeit, um Folgefehler zu minimieren, und eben auch das Datentypen wie double, mit ihren 64 Bit, allein von ihrem Wertebereich nicht ausreichend sind. Wenn man davon ausgeht, dass das "unendlich" nicht ganz wörtlich zu nehmen ist und doch eine endliche Anzahl Zahlen berechnet werden sollen. Ich gehe davon aus, das mit "verrechnen" nicht die Ablage einer Formel gemeint ist.
 
Dies impliziert die größtmögliche Genauigkeit, um Folgefehler zu minimieren, und eben auch das Datentypen wie double, mit ihren 64 Bit, allein von ihrem Wertebereich nicht ausreichend sind.
Naja, solche Aufgabenstellungen setzen ja immer auch eine gewisse Interpretation voraus.

Wenn beispielsweise davon die Rede ist, dass "beliebig viele" Kisten (bei der bekannten Kistenaufgabe) angelegt werden können sollen, interpretiere ich das als "aha, die Anzahl der Kisten soll dynamisch sein" und nicht als wirklich "beliebig" viele. Irgendwo muss man die Kirche im Dorf lassen.

Hier bin ich jetzt davon ausgegangen, dass "unendlich viele Zahlen" eher ein Hinweis darauf sein soll, dass man möglichst schnell die Operatoren anwendet (womit tatsächlich beliebig viele Rechnungen durchgeführt werden können), als dass es auf Genauigkeit ankäme. Zumal diese mit einem double im Bereich des durchaus Üblichen wäre.
 

Neue Themen


Zurück
Oben