JavaScript Wie wird eine Dezimalzahl mit zwei Nachkommastellen in einen Bruch umgewandelt?

kali-hi

Banned
Registriert
Sep. 2025
Beiträge
760
Irgendwie habe ich gerade eine Denkblockade... :(

Wie wird eine Dezimalzahl mit genau zwei Nachkommastellen in einen Bruch umgewandelt?

Also, reelle Zahl -> rationale Zahl.

Zum Beispiel: 2,52
 
WIllst du die funktion selber implementieren, oder eine Library nutzen?
Was stellst du dir unter umwandeln vor? Die zahl bleibt doch gleich.


Hint: ggT ;)

kali-hi schrieb:
Also, reelle Zahl -> rationale Zahl.
Eine Dezimalzah lwie hier beschrieben ist bereits rational
Ergänzung ()

@Benna deine suche tut was anderes, aber mit IEEE754 sollte man sich auch eh mal irgendwann beschäftigt haben..
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: HtOW
madmax2010 schrieb:
WIllst du die funktion selber implementieren, oder eine Library nutzen?
Selber implementieren, moment ich poste ein Beispiel.

madmax2010 schrieb:
Eine Dezimalzahl mit genau zwei Nachkommastellen ist bereits rational
Ja, bitte verzeihe meine Ausdrucksweise.
 
0.53 sind 53 hundertstel. c'mon...
 
  • Gefällt mir
Reaktionen: Manou und whats4
Es geht um die Funktion convertToFractionalMatrix in Zeile 67. Ich weiß nicht, was ich da schreiben soll:

Javascript:
class GaussJordan {
    constructor(matrix) {
        this.message = "";
        this.matrix = matrix;
        this.rows = matrix.length;
        this.cols = matrix[0].length;

        for (let i = 0; i < this.rows; i++) {
            if (this.matrix[i].length !== this.rows + 1) {
                this.appendMessage("Invalid matrix dimensions");
                throw "Invalid matrix dimensions";
            }
        }
    }

    appendMessage(message) {
        this.message += message + "\n";
    }

    getMessage() {
        return this.message;
    }

    print() {
        for (let i = 0; i < this.rows; i++) {
            let s = "";
            for (let j = 0; j < this.cols; j++) {
                s += Number(this.matrix[i][j]).toFixed(2) + "  ";
            }
            this.appendMessage(s);
        }
        this.appendMessage("");
    }

    reduceRow(r1, r2, pos) {
        if (r1.length != r2.length) {
            return false;
        }

        let factor = r2[pos] / r1[pos];
        for (let i = pos; i < r1.length; i++) {
            r2[i] -= factor * r1[i];
        }
        return true;
    }

    normalizeMatrixVariablesToOne() {
        let result = true;
        for (let i = 0; i < this.rows; i++) {
            for (let j = 0; j < this.cols - 1; j++) {
                if (i == j) {
                    if (this.matrix[i][j] == 0) {
                        throw "Division by zero";
                    }
                    continue;
                }
                if (this.matrix[i][j] != 0) {
                    result = false;
                }
            }
            this.matrix[i][this.cols - 1] = this.matrix[i][this.cols - 1] / this.matrix[i][i];
            this.matrix[i][i] = 1.0;
        }
        return result;
    }

    convertToFractionalMatrix() {
        for (let i = 0; i < this.rows; i++) {
            // this.matrix[i][this.cols - 1] = math.fraction(this.matrix[i][this.cols - 1]);

        }
    }

    solve() {
        let k; // pivot
        let swapTemp;

        for (let i = 0; i < this.rows; i++) {
            k = i;

            for (let j = i + 1; j < this.rows; j++) {
                if (this.matrix[j][i] > this.matrix[k][i]) {
                    k = j;
                }
            }

            if (this.matrix[k][i] == 0) {
                this.appendMessage("System of equations contains free variables");
                return;
            }

            // Swap the rows i and k
            swapTemp = this.matrix[i];
            this.matrix[i] = this.matrix[k];
            this.matrix[k] = swapTemp;

            // Iterate over all subsequent rows
            for (let j = 0; j < this.rows; j++) {
                // Reduce row by row
                if (
                    i != j &&
                    !this.reduceRow(this.matrix[i], this.matrix[j], i)
                ) {
                    this.appendMessage("System of equations cannot be solved");
                    return;
                }
            }

            this.print();
        }

        if (!this.normalizeMatrixVariablesToOne()) {
            this.appendMessage("System of equations cannot be fully normalized");
        }
        this.print();

        this.convertToFractionalMatrix();
        this.print();
    }
}

madmax2010 schrieb:
0.53 sind 53 hundertstel
Ja, wahr... Aber wie kommt man dann auf 63/25 ?
 
wie viel 100stel (schreibt man das so im deutschen?) ist 1?
wie viel 25stel ist 1?
 
Allgemein:
  • a = Anfangszahl
  • b = Anzahl der Nachkommastellen
  • c = 10^b
  • d = a*c
  • e = ggT(d, c)
  • f = d/e -> Zähler
  • g = c/e -> Nenner
 
  • Gefällt mir
Reaktionen: BAGZZlash, Fabii02 und kali-hi
@madmax2010 Also rechne ich einfach (immer) 100 / 52, das wären 50 / 26 und 25 / 13. Dann noch den Vorkommateil hinzu: 2+25/13 ... aber das passt nicht.
Ergänzung ()

Oh, 13 und 25 vertauscht. :freak:
Ergänzung ()

madmax2010 schrieb:
wie viel 100stel (schreibt man das so im deutschen?)
Man schreibt Hundertstel oder 100-stel.
Ergänzung ()

Oder Zenti- :D
Ergänzung ()

... schau vorsichtshalber selber nach: https://flexikon.doccheck.com/de/Präfix_für_Maßeinheiten
Ergänzung ()

kali-hi schrieb:
Nein, auch falsch...

1766263708993.png


https://www.duden.de/sprachwissen/s...ch#:~:text=Ob 80-prozentig, 12-,, 68er, 20%ig.
 
Zuletzt bearbeitet:
Beispiel:
  • a = 2,52
  • b = 2
  • c = 10^2 = 100
  • d = 2,52*100 = 252
  • e = ggT(252, 100) = 4
  • f = 252/4 = 63
  • g = 100/4 = 25
Das Ergebnis wäre folglich 63/25. Die Unklarheit scheint bei dir beim ggT zu liegen. Diesen benötigst du zum Kürzen des Bruchs. Wie du diesen ermittelst, wirst du schon selbst herausfinden, das Stichwort hast du ja jetzt. Viel Spaß! ;)
 
  • Gefällt mir
Reaktionen: HtOW, BAGZZlash, Fabii02 und 2 andere
@SaschaHa Der ggT ist nicht so das Problem, irgendwie kam ich vorher gar nicht bis zur Variablen e. :D Danke für die Hilfe.
 
  • Gefällt mir
Reaktionen: SaschaHa
Ggt war auch nur ein ganz grober Hinweis in die Richtung den Bruch zu kürzen wie @SaschaHa vorgerechnet hat.

Ob du jetzt als Bruch 500/1000 oder 1/2 hast ist die gleiche Zahl. Oder 0.5 oder 5/10 oder 50/100.
Zur Not nimm die Länge der Zahl als nenner. Zähler drauf und kürzen soweit du Lust hast
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: kali-hi
Ich habe mal ne doofe Frage: Es geht da nur um die Anzeige?
Also wäre es nicht besser, die ganzen Rechnungen direkt mit Rationalen Zahlen zu machen, mit entsprechenden Typen, die also Zähler und Nenner kennen, anstatt am Ende zu hoffen, dass der Wert mit 2 Dezimalstellen in einen Bruch umgewandelt werden kann, der nahe an dem Wert ist, den die Zahl (die ja vermutlich gerundet sein dürfte?) repräsentieren soll?
 
  • Gefällt mir
Reaktionen: Manou, kali-hi und madmax2010
@tollertyp Der Benutzer soll hinterher beide Geschmacksrichtungen sehen können, also einmal die Variante x.xx und einmal xx/xx, je nach dem, was bevorzugt ist. Und auf sehr hohe Genauigkeiten kommt es hierbei auch nicht an.
 
Nur zur Info.
Das Kürzen wird oft bei Servo-Regler angewandt. Zumindest mache ich es.
Gerade, wenn man mehrere Getriebestufen hat, kann es zu Drifts kommen, wenn man nur die gerundeten Getriebeübersetzungsangaben (i = x.yyy) verwendet.
Man verrechnet alle Zähne der Zahnräder (Antrieb/Abtrieb // Zähler/Nenner).
Dann kürzt man das Ergebnis mit ggT meist auf einen sehr viel kleineren Z/N-Wert.
Die Servo-Regler arbeiten intern mit Ganzahlen/Integer (32/64 bit).
Da sind große Werte für Z/N nicht optimal.
 
  • Gefällt mir
Reaktionen: kali-hi
Hab's gelöst. Gegeben sei das LGS:

Code:
2 9 5
2 4.5 3

Die Lösung ist:

Code:
2.00  9.00  5.00 
0.00  -4.50  -2.00 

2.00  0.00  1.00 
0.00  -4.50  -2.00 

1.00  0.00  0.50 
0.00  1.00  0.44 

1.00  0.00  1/2 
0.00  1.00  11/25

(Ja ok, ein vielleicht zu einfaches Beispiel gewählt...)

Javascript:
class GaussJordan {
    constructor(matrix) {
        this.message = "";
        this.matrix = matrix;
        this.rows = matrix.length;
        this.cols = matrix[0].length;

        for (let i = 0; i < this.rows; i++) {
            if (this.matrix[i].length != this.rows + 1) {
                this.appendMessage("Invalid matrix dimensions");
                throw "Invalid matrix dimensions";
            }
        }
    }

    appendMessage(message) {
        this.message += message + "\n";
    }

    getMessage() {
        return this.message;
    }

    ggT(a, b) {
        if (b == 0) {
            return a;
        }
        return this.ggT(b, a % b);
    }

    print(fractional = false) {
        for (let i = 0; i < this.rows; i++) {
            let s = "";
            for (let j = 0; j < this.cols; j++) {
                if (fractional) {
                    let v = this.matrix[i][j];
                    if (v != 0 && v != 1) {
                        let a = Math.round(Number(v).toFixed(2) * 100.0);
                        let b = 100;
                        let ggt = this.ggT(a, b);
                        s += (a / ggt) + "/" + (b / ggt) + "  ";
                    } else {
                        s += Number(v).toFixed(2) + "  ";
                    }
                } else {
                    s += Number(this.matrix[i][j]).toFixed(2) + "  ";
                }
            }
            this.appendMessage(s);
        }
        this.appendMessage("");
    }

    reduceRow(r1, r2, pos) {
        if (r1.length != r2.length) {
            return false;
        }

        let factor = r2[pos] / r1[pos];
        for (let i = pos; i < r1.length; i++) {
            r2[i] -= factor * r1[i];
        }
        return true;
    }

    normalizeMatrixVariablesToOne() {
        let result = true;
        for (let i = 0; i < this.rows; i++) {
            for (let j = 0; j < this.cols - 1; j++) {
                if (i == j) {
                    if (this.matrix[i][j] == 0) {
                        return false;
                    }
                    continue;
                }
                if (this.matrix[i][j] != 0) {
                    result = false;
                }
            }
            this.matrix[i][this.cols - 1] = this.matrix[i][this.cols - 1] / this.matrix[i][i];
            this.matrix[i][i] = 1.0;
        }
        return result;
    }

    solve() {
        let k; // pivot
        let swapTemp;

        for (let i = 0; i < this.rows; i++) {
            k = i;

            for (let j = i + 1; j < this.rows; j++) {
                if (this.matrix[j][i] > this.matrix[k][i]) {
                    k = j;
                }
            }

            if (this.matrix[k][i] == 0) {
                this.appendMessage("System of equations contains free variables");
                return;
            }

            // Swap the rows i and k
            swapTemp = this.matrix[i];
            this.matrix[i] = this.matrix[k];
            this.matrix[k] = swapTemp;

            // Iterate over all subsequent rows
            for (let j = 0; j < this.rows; j++) {
                // Reduce row by row
                if (
                    i != j &&
                    !this.reduceRow(this.matrix[i], this.matrix[j], i)
                ) {
                    this.appendMessage("System of equations cannot be solved");
                    return;
                }
            }

            this.print();
        }

        if (!this.normalizeMatrixVariablesToOne()) {
            this.appendMessage("System of equations cannot be fully normalized");
        }
        this.print();
        this.print(true);
    }
}

Ich musste also nur die print-Funktion in Zeile 31 anpassen.
 
  • Gefällt mir
Reaktionen: SaschaHa
Sinnvollerweise würde man die Darstellung der Zahl entkoppeln, z.B. so (pseudo-code(*)):
C++:
NumberFormatter::SetPrintFormat(PrintFormat::Fraction);
NumberFormatter::SetWidth(6); // Two digits for numerator/denominator + fraction symbol + sign
for(auto row: matrix) {
    for(auto element: row) {
        NumberFormatter::PrintNumber(element);
    }
    PrintRowDelimiter();
}

(*) Ok, technisch gesehen ist es C++, nicht Puseudo-Code, aber modernes C++ ist oft genau so leicht zu lesen.
 
  • Gefällt mir
Reaktionen: kali-hi
BeBur schrieb:
die Darstellung der Zahl entkoppeln
Das hab ich doch getan :freak:
Ergänzung ()

Es lässt sich auch weiter vereinfachen:

Javascript:
        ggT(a, b) {
            if (b == 0) {
                return a;
            }
            return this.ggT(b, a % b);
        }

        print(fractional = false) {
            for (let i = 0; i < this.rows; i++) {
                let s = "";
                for (let j = 0; j < this.cols; j++) {
                    let v = this.matrix[i][j];
                    if (fractional && v != 0 && v != 1) {
                        let a = parseInt(v * 100.0);
                        let b = 100;
                        let ggt = this.ggT(a, b);
                        s += (a / ggt) + "/" + (b / ggt) + "  ";
                    } else {
                        s += Number(v).toFixed(2) + "  ";
                    }
                }
                this.appendMessage(s);
            }
            this.appendMessage("");
        }

Es gibt aber ein Problem, zum Beispiel bei 2/3:

Code:
3.00  2.00 

1.00  0.67 

1.00  33/50

Eigentlich sollten es hier 2/3 sein, nicht 33/50 ... Hat jemand dazu eine Idee? Ich runde ja bereits immer ab.

Vielleicht muss ich mir doch die Mühe machen, und bei allen Berechnungen mit reinen rationalen Zahlen rechnen... :heul:
 
Zuletzt bearbeitet:
Nun, 2/3 ist nunmal keine
kali-hi schrieb:
Dezimalzahl mit genau zwei Nachkommastellen
Und 67/100 ist weder 33/50 noch 2/3.

Falls du tatsächlich exakte rationale Ergebnisse haben möchtest, wäre das Rechnen mit Brüchen vermutlich das Einfachste.
 
  • Gefällt mir
Reaktionen: kali-hi
2/3 ist eine periodische Dezimalzahl, als reelle Zahl wäre sie also unendlich lang und kommt folglich nicht ohne Rundung aus. Bei solchen Zahlen macht eine Umwandlung daher keinen Sinn.
 
  • Gefällt mir
Reaktionen: kali-hi und madmax2010

Ähnliche Themen

Zurück
Oben