Solusi masalah akurasi perhitungan numerik dalam desain strategi JavaScript

Penulis:Kebaikan, Dibuat: 2020-07-09 11:31:01, Diperbarui: 2023-10-28 15:32:47

img

Ketika menulis strategi JavaScript, karena beberapa masalah dari bahasa skrip itu sendiri, sering menyebabkan masalah akurasi numerik dalam perhitungan.1 - 0.8atau0.33 * 1.1, data kesalahan akan dihitung:

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

img

Jadi bagaimana kita menyelesaikan masalah-masalah seperti itu?

Perkembangan maksimum nilai titik layang adalah 17 tempat desimal, tetapi akurasi jauh lebih buruk daripada bilangan bulat ketika melakukan operasi; bilangan bulat dikonversi menjadi desimal saat melakukan operasi; dan saat menghitung operasi desimal dalam Java dan JavaScript, keduanya Pertama mengkonversi desimal desimal ke biner yang sesuai, sebagian desimal tidak dapat sepenuhnya dikonversi menjadi biner, inilah kesalahan pertama. Setelah desimal dikonversi menjadi biner, maka operasi antara biner dilakukan untuk mendapatkan hasil biner. Kemudian mengkonversi hasil biner menjadi desimal, di mana kesalahan kedua biasanya terjadi.

Untuk memecahkan masalah ini, saya mencari beberapa solusi di Internet, dan menguji dan menggunakan solusi berikut untuk memecahkan masalah ini:

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

Prinsipnya adalah untuk mengkonversi dua operand yang akan dihitung menjadi bilangan bulat untuk dihitung untuk menghindari masalah akurasi.

Dengan cara ini, ketika kita ingin program untuk menempatkan pesanan ketika harga pasar ditambah presisi harga minimum, kita tidak perlu khawatir tentang akurasi numerik

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]) 
}

Pedagang yang tertarik dapat membaca kode, memahami proses perhitungan, dipersilakan untuk mengajukan pertanyaan, belajar bersama dan maju bersama.


Berkaitan

Lebih banyak