Có thể thiết lập, thậm chí gần như thế nào, mất chính xác tối đa khi xử lý hai giá trị double
trong java (cộng/trừ)? Có lẽ kịch bản trường hợp xấu nhất là khi hai số không thể được biểu diễn chính xác, và sau đó một thao tác được thực hiện trên chúng, điều này dẫn đến một giá trị không thể được biểu diễn chính xác.Java - mất tối đa độ chính xác trong một phép cộng/trừ đôi
Trả lời
Hãy xem Math.ulp(double)
. ulp của một double
là delta đến giá trị cao nhất tiếp theo. Ví dụ, nếu bạn thêm vào số và một nhỏ hơn ulp của số khác, bạn biết rằng việc bổ sung sẽ không có hiệu lực. Nếu bạn nhân hai số nhân đôi, bạn có thể nhân số điểm của họ để có được lỗi tối đa của kết quả.
Đây chính xác là những gì tôi muốn – Bober02
Trường hợp xấu nhất là tất cả chính xác có thể bị mất. Điều này có thể xảy ra nếu kết quả lớn hơn số hữu hạn có thể biểu diễn lớn nhất. Sau đó, nó sẽ được lưu trữ như POSITIVE_INFINITY (hoặc NEGATIVE_INFINITY).
Về bản cập nhật của bạn, điều này có thể xảy ra với việc bổ sung.
double a = Double.MAX_VALUE;
System.out.println(a);
double b = a + a;
System.out.println(b);
Kết quả:
1.7976931348623157E308
Infinity
Xem nó trực tuyến: ideone
Nói chung kích thước của các lỗi đại diện là tương đối so với kích thước của con số của bạn.
Xem chỉnh sửa ở trên - Tôi có nghĩa là bổ sung chủ yếu ... – Bober02
Bạn có thể có một cái nhìn tại các độ chính xác thực tế của nguyên liệu đầu vào của bạn, ví dụ mã bên dưới kết quả đầu ra:
input: 0.01000000000000000020816681711721685132943093776702880859375
range: [0.0099999999999999984734433411404097569175064563751220703125 - 0.010000000000000001942890293094023945741355419158935546875]
range size: 3.4694469519536141888238489627838134765625E-18
input: 10000000000000000
range: [9999999999999998 - 10000000000000002]
range size: 4
public static void main(String[] args) {
printRange(0.01);
printRange(10000000000000000d);
}
private static void printRange(double d) {
long dBits = Double.doubleToLongBits(d);
double dNext = Double.longBitsToDouble(dBits + 1);
double dPrevious = Double.longBitsToDouble(dBits + -1);
System.out.println("input: " + new BigDecimal(d));
System.out.println("range: [" + new BigDecimal(dPrevious) + " - " + new BigDecimal(dNext) + "]");
System.out.println("range size: " + new BigDecimal(dNext - dPrevious));
}
Bạn vẫn sẽ cần phải sau đó ước tính thiệt hại trên kết quả của bạn hoạt động. Và điều đó không làm việc với các trường hợp góc (khoảng Infinity, NaN, vv).
- 1. Độ chính xác của phép nhân đôi chính xác trong java?
- 2. mất bất ngờ độ chính xác khi chia đôi
- 3. Mất chính xác với đôi C++
- 4. Độ chính xác gấp đôi mở rộng
- 5. Lỗi Java: có thể mất chính xác
- 6. Chuỗi C++ để nhân đôi chuyển đổi mất chính xác?
- 7. JDBC ResultSet getDate mất độ chính xác
- 8. OpenCL đôi độ chính xác khác nhau từ CPU chính xác đôi
- 9. Tại sao độ chính xác tùy ý trong các chữ cái kép được phép trong Java?
- 10. Format độ chính xác gấp đôi trong PostgreSQL
- 11. Độ chính xác tối đa của Bộ hẹn giờ trong .NET là bao nhiêu?
- 12. Định dạng chuỗi trong scala - độ chính xác thập phân tối đa
- 13. Mức độ kế thừa tối đa trong java là gì?
- 14. Tìm số nguyên tối đa mà một loại dấu phẩy động có thể xử lý mà không mất độ chính xác
- 15. Hibernate mất độ chính xác trong kết quả khi ánh xạ một số (22,21) để BigDecimal
- 16. Đặt độ dài tối đa của một TextBlock trong XAML
- 17. Độ dài tối đa của một openID
- 18. WebAPI, JSON.Net và mất độ chính xác thập phân
- 19. Thuật toán tốt nhất để tránh mất độ chính xác?
- 20. Java chính xác đôi với -hằng/bộ phận
- 21. Độ dài byte tối đa []?
- 22. Số lượng cookie tối đa được phép
- 23. Tọa độ GPS chính xác
- 24. Độ dài ký tự tối đa UUID
- 25. độ chính xác chiều sâu opencv độ chính xác
- 26. Số lượng cột tối đa được phép trong chế độ xem SQL Server 2008 là gì?
- 27. đôi trừ đôi cho vấn đề chính xác
- 28. Tối đa hóa JInternalFrame trong Java
- 29. SQL server 2005 mất chính xác số
- 30. Thư viện có độ chính xác cao điểm nổi Java
Nếu mất chính xác là một vấn đề, tôi khuyên bạn nên sử dụng BigDecimal thay vì tăng gấp đôi. –
Vâng, toàn bộ điểm của câu hỏi này là để xem mức độ mất mát lớn như thế nào. double chiếm 8 byte, trong khi BigDecimal khoảng 40, và tôi cần lưu trữ rất nhiều điểm dữ liệu – Bober02
Khi bạn thực hiện nhiều thao tác dấu phẩy động, hiệu suất của việc sử dụng nguyên thủy thay vì các đối tượng có thể là đáng kể. – Cephalopod