2011-11-11 34 views
5

Đây có phải là trục trặc trong Java không?Lỗi Java? Trừ số?

tôi đi đến giải quyết biểu thức này: 3,1-7,1

tôi nhận được câu trả lời: -3,9999999999999996

gì đang xảy ra ở đây?

+15

Số học dấu chấm động là những gì đang diễn ra. –

+0

Xem những thứ như [this] (http://stackoverflow.com/questions/2798830/double-precision-values) và hàng tấn khác. (Hey, bài viết của WECSSKAFPN ở đâu?) –

+2

Điều này đã trở thành câu hỏi lập trình phổ biến nhất. .... –

Trả lời

10

Có thể tìm thấy giải thích tuyệt vời tại đây. http://www.ibm.com/developerworks/java/library/j-jtp0114/

Số học dấu chấm động hiếm khi chính xác. Trong khi một số số, chẳng hạn như là 0,5, có thể được biểu diễn chính xác dưới dạng số thập phân (cơ sở 2) (kể từ 0,5 bằng 2-1), các số khác, chẳng hạn như 0,1, không thể. Do đó, các thao tác dấu chấm động có thể dẫn đến lỗi làm tròn, cho kết quả là gần với - nhưng không bằng - kết quả mà bạn có thể mong đợi. Ví dụ, việc tính toán đơn giản dưới đây kết quả trong 2,600000000000001, chứ không phải là 2.6:

double s=0; 

for (int i=0; i<26; i++) 
    s += 0.1; 
System.out.println(s); 

Tương tự, nhân 0,1 * 26 mang lại một kết quả khác với thêm .1 cho chính nó 26 lần. Các lỗi làm tròn trở nên nghiêm trọng hơn khi truyền từ dấu phẩy động sang số nguyên, bởi vì việc đúc thành một loại tích phân loại bỏ phần không tách rời, ngay cả khi tính toán là "trông giống như" chúng phải có giá trị tích phân. Ví dụ, câu sau đây:

double d = 29.0 * 0.01; 
    System.out.println(d); 
    System.out.println((int) (d * 100)); 

sẽ sản xuất như đầu ra:

0.29 
    28 

mà có lẽ không phải những gì bạn có thể mong đợi ban đầu.

Xem tham chiếu được cung cấp để biết thêm thông tin.

1

Máy vi tính là 100% trong thế giới toán học đúng, đối với người bình thường thì không. Java không có một lỗi trên một số cụ thể vì nó chỉ là mã chạy theo cùng một cách nhưng có một đầu vào khác nhau!

P.S. Google làm thế nào để làm tròn một số

+0

Cảm ơn người đàn ông. Điều này thực sự lạ ... – Confiqure

+0

'Java không thể có lỗi'? Tôi chưa bao giờ gặp một hệ thống máy tính không có lỗi .... –

+0

Không, tôi có nghĩa là trong một bổ sung đơn giản, nó giống như nói 5 + 5 sẽ đúng 6 + 5 wont, – Hego555

1

lỗi làm tròn tại các điểm nổi

cùng cách mà 3 * 0.1 != 0.3 (khi nó không gập bởi trình biên dịch ít nhất)

2

Như đã đề cập bởi một số người khác, bạn không thể đếm số double nếu bạn muốn nhận giá trị thập phân chính xác, ví dụ: khi triển khai các ứng dụng tiền tệ.Thay vào đó, bạn nên xem xét kỹ hơn BigDecimal:

BigDecimal a = new BigDecimal("3.1"); 
BigDecimal b = new BigDecimal("7.1"); 
BigDecimal result = a.subtract(b); 
System.out.println(result);  // Prints -4.0 
Các vấn đề liên quan