2014-12-26 59 views
5

Tại sao xác nhận này không thành công?Tại sao không phải! Int() hoạt động bình thường?

import std.conv; 

void main() 
{ 
    auto y = 0.6, delta=0.1; 
    auto r = to!int(y/delta); 
    assert(r == 6); 
} 

giá trị của r phải là 6 nhưng vẫn là 5, Tại sao?

+3

[Toán học dấu chấm động bị hỏng?] (Http://stackoverflow.com/questions/588004/is-floating-point -math-broken) [Điều mà mọi lập trình viên nên biết về số học dấu chấm động] (http://floating-point-gui.de/) –

+2

sau đó đọc bài viết kỹ lưỡng này [Mỗi nhà khoa học máy tính nên biết gì về số học dấu chấm động ] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) –

Trả lời

5

Điều này có lẽ do 0.6 không thể được biểu diễn hoàn toàn bằng số dấu phẩy động. Bạn viết 0.6, nhưng đó không phải chính xác những gì bạn nhận được - bạn nhận được một cái gì đó giống như 0.599999999. Khi bạn chia cho 0,1, bạn nhận được một cái gì đó giống như 5,99999999, mà chuyển đổi thành một số nguyên của 5 (bằng cách làm tròn xuống).

Ví dụ trong các ngôn ngữ khác:

C#: Why is (double)0.6f > (double)(6/10f)?

Java: Can someone please explain me that in java why 0.6 is <0.6f but 0.7is >=0.7f

+1

Làm thế nào tôi có thể làm tròn lên? – Algo

+2

Bạn có thể làm tròn số nguyên gần nhất với std.math.round: http://dlang.org/library/std/math/round.html. Nếu bạn biết kết quả dấu phẩy động của bạn nằm trong vòng 0,5 của số nguyên bạn muốn, điều này sẽ làm tròn kết quả cho những gì bạn muốn. Hai câu trả lời cho giá của một! –

+0

Hoặc bằng cách thêm 0,5. I. sử dụng (y/delta + 0,5) – runec

4

Máy tính đại diện cho các số dấu phảy trong hệ nhị phân. Các số thập phân 0,6 và 0,1 không có biểu diễn nhị phân chính xác, trong khi số bit được sử dụng để biểu diễn chúng là hữu hạn. Kết quả là, sẽ có cắt ngắn, có hiệu lực được nhìn thấy trong quá trình phân chia. Kết quả của phân chia đó không chính xác là 6.00000000, nhưng có lẽ là 5.99999999, sau đó được cắt ngắn thành 5.

Các vấn đề liên quan