Giải pháp cho vấn đề tính toán số chính xác trong thiết kế chiến lược JavaScript

Tác giả:Tốt, Tạo: 2020-07-09 11:31:01, Cập nhật: 2023-10-28 15:32:47

img

Khi viết các chiến lược JavaScript, do một số vấn đề của ngôn ngữ kịch bản, nó thường dẫn đến các vấn đề về độ chính xác số trong tính toán. Nó có một ảnh hưởng nhất định đến một số tính toán và phán đoán logic trong chương trình. Ví dụ: khi tính toán1 - 0.8hoặc0.33 * 1.1, dữ liệu lỗi sẽ được tính:

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

img

Vậy làm thế nào để giải quyết những vấn đề như vậy?

Tiến trình tối đa của các giá trị dấu phẩy động là 17 vị trí thập phân, nhưng độ chính xác tồi tệ hơn nhiều so với số nguyên khi thực hiện các hoạt động; số nguyên được chuyển đổi thành số thập phân khi thực hiện các hoạt động; và khi tính toán các hoạt động thập phân trong Java và JavaScript, cả hai Đầu tiên chuyển đổi số thập phân thành số nhị phân tương ứng, một phần của số thập phân không thể được chuyển đổi hoàn toàn thành nhị phân, đây là lỗi đầu tiên. Sau khi các số thập phân được chuyển đổi thành nhị phân, sau đó hoạt động giữa số nhị phân được thực hiện để có được kết quả nhị phân. Sau đó chuyển đổi kết quả nhị phân thành số thập phân, nơi một lỗi thứ hai thường xảy ra.

Để giải quyết vấn đề này, tôi đã tìm kiếm một số giải pháp trên Internet, và thử nghiệm và sử dụng các giải pháp sau để giải quyết vấn đề này:

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

Nguyên tắc là chuyển đổi hai toán tử được tính thành số nguyên để tính toán để tránh các vấn đề về độ chính xác.

Bằng cách này, khi chúng ta muốn chương trình đặt một lệnh khi giá thị trường cộng với một mức độ chính xác giá tối thiểu, chúng ta không phải lo lắng về độ chính xác số

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

Các nhà giao dịch quan tâm có thể đọc mã, hiểu quy trình tính toán, được chào đón để đặt câu hỏi, cùng nhau học hỏi và cùng nhau tiến bộ.


Có liên quan

Thêm nữa