Vì 1.1
và 3.3
là floating point numbers. Các phân số thập phân, chẳng hạn như .1 hoặc .3, không thể biểu diễn chính xác trong một số dấu phẩy động nhị phân. .1 nghĩa là 1/10. Để biểu diễn điều đó theo dạng nhị phân, trong đó mỗi số phân số đại diện cho 1/2 n (1/2, 1/4, 1/8, v.v.), bạn sẽ cần một số lượng vô hạn các chữ số, 0.000110011 ... lặp lại vô hạn.
Đây chính là vấn đề tương tự như đại diện, ví dụ, 1/3 trong cơ sở 10. Trong cơ sở 10, bạn sẽ cần một số lượng vô hạn các chữ số, .33333 ... mãi mãi, để đại diện cho 1/3 chính xác. Vì vậy, làm việc trong cơ sở 10, bạn thường tròn, để một cái gì đó như. 33. Nhưng nếu bạn thêm ba bản sao của số đó, bạn nhận được 0,99, không phải 1.
Để biết thêm thông tin về chủ đề, hãy đọc What Every Computer Scientist Should Know About Floating Point Arithmetic.
Để biểu diễn số hữu tỷ chính xác hơn trong Haskell, bạn luôn có thể sử dụng loại dữ liệu hợp lý, Ratio
; kết hợp với bignums (số lượng lớn tùy ý, Integer
trong Haskell, trái ngược với Int
có kích thước cố định) là loại cho tử số và mẫu số, bạn có thể biểu diễn số hữu tỉ chính xác tùy ý, nhưng với tốc độ chậm hơn đáng kể so với số dấu phẩy động. được triển khai trong phần cứng và được tối ưu hóa cho tốc độ.
Số dấu phẩy động là một tối ưu hóa, để tính toán khoa học và số, có tính chính xác cho tốc độ cao, cho phép bạn thực hiện một số lượng lớn các tính toán trong một thời gian ngắn, miễn là bạn biết nó ảnh hưởng đến tính toán của bạn.
Đẹp javascript float - thập phân - nhị phân visualizer: http://babbage.cs.qc.edu/IEEE-754/Decimal.html – Seth
Đây không phải là một vấn đề Haskell cụ thể: điều tương tự sẽ xảy ra trong bất kỳ ngôn ngữ nào sử dụng số dấu phẩy động. Các chi tiết chính xác phụ thuộc vào việc thực hiện điểm nổi, nhưng hầu hết các bộ vi xử lý sử dụng IEEE-754, được chỉ định chặt chẽ để đảm bảo rằng các chương trình hoạt động sai theo cách giống hệt nhau ở mọi nơi. –