Bản năng của bạn về cơ bản là đúng, sắp xếp theo thứ tự tăng dần (về độ lớn) thường cải thiện được phần nào mọi thứ. Hãy xem xét trường hợp chúng ta đang thêm số float chính xác đơn (32 bit) và có 1 tỷ giá trị bằng 1 / (1 tỷ) và một giá trị bằng 1. Nếu giá trị 1 đứng trước thì tổng sẽ đến thành 1, vì 1 + (1/1 tỷ) là 1 do mất độ chính xác. Mỗi phép cộng không ảnh hưởng gì đến tổng số.
Nếu các giá trị nhỏ đến trước, ít nhất chúng sẽ cộng lại thành một cái gì đó, mặc dù ngay cả khi đó tôi có 2 ^ 30 trong số đó, trong khi sau 2 ^ 25 hoặc lâu hơn, tôi quay lại tình huống mỗi giá trị riêng lẻ không ảnh hưởng đến tổng nữa không. Vì vậy, tôi vẫn sẽ cần nhiều thủ thuật hơn.
Đó là một trường hợp cực đoan, nhưng nói chung việc thêm hai giá trị có độ lớn tương tự nhau sẽ chính xác hơn là thêm hai giá trị có độ lớn rất khác nhau, vì bạn "loại bỏ" ít bit độ chính xác hơn ở giá trị nhỏ hơn theo cách đó. Bằng cách sắp xếp các số, bạn nhóm các giá trị có độ lớn tương tự lại với nhau và bằng cách thêm chúng theo thứ tự tăng dần, bạn cho các giá trị nhỏ "cơ hội" tích lũy đạt đến độ lớn của các số lớn hơn.
Tuy nhiên, nếu có liên quan đến các số âm thì rất dễ "qua mặt" cách tiếp cận này. Hãy xem xét ba giá trị để tính tổng {1, -1, 1 billionth}
,. Tổng đúng về mặt số học là 1 billionth
, nhưng nếu phép cộng đầu tiên của tôi liên quan đến giá trị nhỏ thì tổng cuối cùng của tôi sẽ là 0. Trong số 6 lệnh có thể, chỉ có 2 lệnh là "đúng" - {1, -1, 1 billionth}
và {-1, 1, 1 billionth}
. Tất cả 6 lệnh đều cho kết quả chính xác ở thang của giá trị có độ lớn lớn nhất trong đầu vào (0,0000001% ra), nhưng đối với 4 lệnh trong số đó, kết quả không chính xác ở thang của giá trị đúng (100%). Vấn đề cụ thể mà bạn đang giải quyết sẽ cho bạn biết liệu vấn đề cũ có đủ tốt hay không.
Trên thực tế, bạn có thể chơi nhiều thủ thuật hơn là chỉ thêm chúng theo thứ tự đã sắp xếp. Nếu bạn có nhiều giá trị rất nhỏ, một số giá trị trung bình và một số lượng nhỏ các giá trị lớn, thì cách chính xác nhất là cộng tất cả các giá trị nhỏ trước, sau đó cộng riêng các giá trị trung bình, cộng hai tổng đó cùng nhau sau đó thêm những cái lớn. Việc tìm ra sự kết hợp chính xác nhất của các phép cộng dấu phẩy động hoàn toàn không phải là chuyện nhỏ, nhưng để đối phó với những trường hợp thực sự tồi tệ, bạn có thể giữ một loạt các tổng đang chạy ở các độ lớn khác nhau, thêm từng giá trị mới vào tổng phù hợp nhất với độ lớn của nó, và khi tổng số đang chạy bắt đầu quá lớn so với độ lớn của nó, hãy thêm nó vào tổng số tiếp theo và bắt đầu một tổng mới. Được coi là cực đoan logic của nó, quá trình này tương đương với việc thực hiện tổng trong một kiểu chính xác tùy ý (vì vậy bạn ' d làm điều đó). Nhưng với sự lựa chọn đơn giản là thêm vào theo thứ tự cường độ tăng dần hoặc giảm dần, tăng dần là đặt cược tốt hơn.
Nó có một số liên quan đến lập trình trong thế giới thực, vì có một số trường hợp mà phép tính của bạn có thể sai rất nặng nếu bạn vô tình cắt bỏ một đuôi "nặng" bao gồm một số lượng lớn các giá trị mà mỗi giá trị quá nhỏ để ảnh hưởng riêng lẻ tổng, hoặc nếu bạn loại bỏ quá nhiều độ chính xác từ nhiều giá trị nhỏ mà chỉ ảnh hưởng đến một vài bit cuối cùng của tổng. Trong trường hợp đuôi không đáng kể, bạn có thể không quan tâm. Ví dụ: nếu bạn chỉ cộng một số lượng nhỏ các giá trị với nhau ngay từ đầu và bạn chỉ sử dụng một vài số liệu quan trọng của tổng.