Lösung des Problems der Genauigkeit der numerischen Berechnung im JavaScript-Strategie-Design

Schriftsteller:Gutes, Erstellt: 2020-07-09 11:31:01, Aktualisiert: 2023-10-28 15:32:47

img

Bei der Erstellung von JavaScript-Strategien führt es aufgrund einiger Probleme der Skriptsprache selbst häufig zu Problemen mit der numerischen Genauigkeit bei Berechnungen.1 - 0.8oder0.33 * 1.1, werden die Fehlerdaten berechnet:

function main() {
    var a = 1 - 0.8
    Log(a)
   
    var c = 0.33 * 1.1
    Log(c) 
}

img

Wie können wir solche Probleme lösen?

Der maximale Fortschritt von Flusskommawerten beträgt 17 Dezimalstellen, aber die Genauigkeit ist bei der Ausführung von Operationen viel schlechter als bei Ganzzahlen; Ganzzahlen werden bei der Ausführung von Operationen in Dezimalstellen umgewandelt; und bei der Berechnung von Dezimalstellen in Java und JavaScript werden beide Erstens das Dezimalpunkt in die entsprechende Binärzahl umgewandelt, ein Teil des Dezimals kann nicht vollständig in binär umgewandelt werden, hier ist der erste Fehler. Nachdem die Dezimalstellen in binär umgewandelt wurden, wird dann die Operation zwischen der Binärzahl durchgeführt, um das binäre Ergebnis zu erhalten. Dann wird das binäre Ergebnis in Dezimalzahl umgewandelt, wo normalerweise ein zweiter Fehler auftritt.

Um dieses Problem zu lösen, habe ich im Internet nach einigen Lösungen gesucht, und die folgenden Lösungen getestet und verwendet, um dieses Problem zu lösen:

function mathService() {
    // addition
    this.add = function(a, b) {
        var c, d, e;
        try {
            c = a.toString().split(".")[1].length;   // Get the decimal length of a
        } catch (f) {
            c = 0;
        }
        try {
            d = b.toString().split(".")[1].length;   // Get the decimal length of b
        } catch (f) {
            d = 0;
        }
        //Find e first, multiply both a and b by e to convert to integer addition, then divide by e to restore
        return e = Math.pow(10, Math.max(c, d)), (this.mul(a, e) + this.mul(b, e)) / e;
    }
    
    // multiplication
    this.mul = function(a, b) {       
        var c = 0,
            d = a.toString(),         // Convert to string 
            e = b.toString();         // ...
        try {
            c += d.split(".")[1].length;      // c Accumulate the fractional digit length of a
        } catch (f) {}
        try {
            c += e.split(".")[1].length;      // c Accumulate the length of decimal places of b
        } catch (f) {}
        // Convert to integer multiplication, then divide by 10^c, move decimal point, restore, use integer multiplication without losing accuracy
        return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
    }

    // Subtraction
    this.sub = function(a, b) {
        var c, d, e;
        try {
            c = a.toString().split(".")[1].length;  // Get the decimal length of a
        } catch (f) {
            c = 0;
        }
        try {
            d = b.toString().split(".")[1].length;  // Get the decimal length of b
        } catch (f) {
            d = 0;
        }
        // Same as addition
        return e = Math.pow(10, Math.max(c, d)), (this.mul(a, e) - this.mul(b, e)) / e;
    }

    // Division
    this.div = function(a, b) {
        var c, d, e = 0,
            f = 0;
        try {
            e = a.toString().split(".")[1].length;
        } catch (g) {}
        try {
            f = b.toString().split(".")[1].length;
        } catch (g) {}
        // Similarly, convert to integer, after operation, restore
        return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), this.mul(c / d, Math.pow(10, f - e));
    }
}

function main() {
    var obj = new mathService()
    
    var a = 1 - 0.8
    Log(a)
    
    var b = obj.sub(1, 0.8)
    Log(b)
    
    var c = 0.33 * 1.1
    Log(c)
    
    var d = obj.mul(0.33, 1.1)
    Log(d)
}

img

Das Prinzip besteht darin, die beiden zu berechnenden Operanden in ganze Zahlen umzuwandeln, um Genauigkeitsprobleme zu vermeiden.

Auf diese Weise, wenn wir wollen, dass das Programm eine Bestellung platziert, wenn der Marktpreis plus eine minimale Preisgenauigkeit, müssen wir uns nicht um numerische Genauigkeit kümmern

function mathService() {
....    // Omitted
}

function main() {
    var obj = new mathService()
    var depth = exchange.GetDepth()
    exchange.Sell(obj.add(depth.Bids[0].Price, 0.0001), depth.Bids[0].Amount, "Buy 1 order:", depth.Bids[0]) 
}

Interessierte Händler können den Code lesen, den Berechnungsvorgang verstehen, Fragen stellen, gemeinsam lernen und gemeinsam Fortschritte machen.


Verwandt

Mehr