Những vấn đề với tính toán dấu chấm động
Số trang: 8
Loại file: pdf
Dung lượng: 191.59 KB
Lượt xem: 1
Lượt tải: 0
Xem trước 2 trang đầu tiên của tài liệu này:
Thông tin tài liệu:
Câu chuyện của chúng ta bắt đầu với đoạn chương trình Visual Basic (VB) sau: Dim a As Double, b As Double, s As Double a = 0.11 b = 0.1 s = 0.21 If s = a + b Then MsgBox "True" Else MsgBox "False" End If Khi chạy, chúng ta sẽ nhận được thông báo sau:Rõ ràng s = a+b vậy mà chương trình lại báo "False" (sai). Phải chăng đó là lỗi của Visual Basic? Bạn nào có ý nghĩ như vậy hãy thử lại với Java - một ngôn ngữ khác hẳn và hoàn toàn không...
Nội dung trích xuất từ tài liệu:
Những vấn đề với tính toán dấu chấm động Những vấn đề với tính toán dấu chấm động Câu chuyện của chúng ta bắt đầu với đoạn chương trình Visual Basic (VB) sau: Dim a As Double, b As Double, s As Double a = 0.11b = 0.1s = 0.21If s = a + b ThenMsgBox TrueElseMsgBox FalseEnd IfKhi chạy, chúng ta sẽ nhận được thông báo sau:Rõ ràng s = a+b vậy mà chương trình lại báo False (sai). Phải chăng đó là lỗi của Visual Basic?Bạn nào có ý nghĩ như vậy hãy thử lại với Java - một ngôn ngữ khác hẳn và hoàn toàn khôngphải do Microsoft cung cấp - sẽ thấy lỗi đó lặp lại giống hệt.Trở về với đoạn chương trình VB ban đầu, nếu đổi các biến a, b, s thành kiểu Currency thìchương trình lại chạy đúng như mong đợi (tức là đưa ra thông báo True). Dài dòng như vậyđể các bạn thấy gốc rễ của vấn đề nằm ở đặc điểm của số dấu chấm động nhị phân và các phéptoán liên quan tới chúng.Không ít lập trình viên chịu bó tay không lý giải được hiện tượng trên. Điều khá ngạc nhiên làcác số dấu chấm động hiện diện ở khắp mọi nơi trong các hệ thống máy tính vậy mà nhiều ngườivẫn không biết hay không quan tâm tới chúng. Hầu hết tất cả các ngôn ngữ lập trình đều có kiểudữ liệu dấu chấm động; các hệ thống điện toán từ máy PC đến siêu máy tính đều có bộ gia tốcdấu chấm động; hầu hết các trình biên dịch đều phải thực hiện việc dịch các thuật toán dấu chấmđộng một các thường xuyên và hầu như tất cả các hệ điều hành đều phải đối mặt với nhữngtrường hợp ngoại lệ của dấu chấm động (chẳng hạn bị tràn bộ nhớ).Một số dấu chấm động là cách biểu diễn cho một số trong một tập con các số hữu tỷ và thườngdùng trong máy tính để biểu diễn gần đúng một số thực bất kỳ. Một cách cụ thể hơn, số dấuchấm động được thể hiện như một số nguyên hay số dấu chấm tĩnh (phần có nghĩa hay phần địnhtrị) nhân với một cơ số (thường là cơ số 2 đối với máy tính) lũy thừa (số mũ) nguyên nào đó.a = m × beTrong một hệ thống như vậy, chúng ta chọn cơ số b và độ chính xác p (số chữ số được lưu). m(phần có nghĩa hay phần định trị) là một số có p chữ số được biểu diễn dưới dạng ±d.ddd...ddd(mỗi số là một số nguyên từ 0 đến b-1). Nếu số đầu tiên của m khác 0 thì nó được coi là đã chuẩnhóa. Một số cách mô tả có sử dụng một bit dấu riêng (s, thay thế cho -1 hoặc +1) và m buộc phảilà số dương, e được gọi là số mũ.Mô hình này cho phép biểu diễn một giải số khá lớn trong một số bit nhỏ mà cách biểu diễn dấuchấm tĩnh không thể hiện được. Ví dụ, một số dấu chấm động với 4 số phần thập phân (b = 10, p= 4) và số mũ trong khoảng ±4 có thể dùng để biểu diễn các số 43210, 4.321 hay 0.0004321,nhưng sẽ không đủ chính xác để biểu diễn cho số 432.123 và 43212.3 (và do đó sẽ được làm trònđến 432.1 và 43210). Trong thực tế số các chữ số thường lớn hơn 4.Ngoài ra, việc biểu diễn dấu chấm động thường bao gồm những giá trị đặc biệt: dương vô cực,âm vô cực và NaN (Not a Number - không phải số). Các giá trị vô cực được sử dụng khi kết quảquá lớn không thể biểu diễn được, còn NaN dùng để kết quả của những phép tính không hợp lệhoặc kết quả không được định nghĩa.Trong ví dụ trên, các con số được biểu diễn trong hệ thập phân (b = 10), hệ thống máy tính cũngthực hiện như vậy trong hệ nhị phân (b = 2). Trong máy tính, số dấu chấm động được xác địnhkích thước bằng số bit dùng để lưu trữ chúng. Kích thước này là 32 bit hoặc 64 bit, thường gọi làđộ chính xác đơn (single-precision) và độ chính xác kép (double-precision). Cũng có một số hệthống đưa ra những kích thước lớn hơn như 80 bit (dòng x86) hay 128 bit (thường được thựchiện bằng phần mềm). Bạn có thể xem cách biểu diễn dấu chấm động nhị phân của các số thậpphân tại trang web http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html.Thuật ngữ dấu chấm động xuất phát từ thực tế rằng không có số xác định các chữ số trước hoặcsau dấu chấm (dấu chấm thập phân có thể di chuyển được). Cách biểu diễn trong đó số các chữsố trước và sau dấu chấm thập phân cố định gọi là dấu chấm tĩnh. Nhìn chung, cách biểu diễnbằng dấu chấm động chậm hơn và thiếu chính xác hơn so với cách biểu diễn dấu chấm tĩnh,nhưng lại có thể biểu diễn được một vùng số lớn hơn.Một phép toán dấu chấm động là một phép toán số học được thực hiện với số dấu chấm động vàthường bao hàm cả phép tính gần đúng hay phép làm tròn bởi vì kết quả của một phép toán cóthể được biểu diễn một cách không chính xác. Do các phép toán với số dấu chấm động đòi hỏinhiều năng lực điện toán nên nhiều bộ vi xử lý thường đi kèm với một chip bổ sung FPU(floating point unit) chuyên dùng cho các phép toán dấu chấm động mà chúng ta thường gọi làbộ đồng xử lý toán học.RẮC RỐI SỐ DẤU CHẤM ĐỘNG NHỊ PHÂN1. Lỗi làm trònVì số dấu chấm động nhị phân không thể biểu diễn chính xác các số thập phân nên việc sử dụngchúng sẽ không thể đảm bảo cho kết quả như khi sử dụng các phép toán thập phân. Điều này gâyrất nhiều khó khăn cho việc phát triển và thử nghiệm các ứng dụng có sử dụng dữ liệu thực nhưthương mại hay tài chính. Dưới đây là một vài ví dụ điển hình.Lấy số 1 chia liên tục cho 10 sẽ cho kết quả như bảng dưới đây: Thập phân Nhị phân 0.1 0.1 0.01 0.01 0.001 9.999999E-4 0.0001 9.999999E-5 0.00001 9.999999E-6 0.000001 9.999999E-7 1E-7 9.999999E-8 1E-8 9.999999E-9 1E-9 9.999999E-10Cột bên trái hiển thị các kết quả mong đợi hay kết quả nhận được khi dùng BigDecimal class củaJava, cột bên phải hiển thị các kết quả nhận được bằng việc sử dụng kiểu dữ liệu float của Java.Các kết quả nhận được từ việc sử dụng kiểu dữ liệu do ...
Nội dung trích xuất từ tài liệu:
Những vấn đề với tính toán dấu chấm động Những vấn đề với tính toán dấu chấm động Câu chuyện của chúng ta bắt đầu với đoạn chương trình Visual Basic (VB) sau: Dim a As Double, b As Double, s As Double a = 0.11b = 0.1s = 0.21If s = a + b ThenMsgBox TrueElseMsgBox FalseEnd IfKhi chạy, chúng ta sẽ nhận được thông báo sau:Rõ ràng s = a+b vậy mà chương trình lại báo False (sai). Phải chăng đó là lỗi của Visual Basic?Bạn nào có ý nghĩ như vậy hãy thử lại với Java - một ngôn ngữ khác hẳn và hoàn toàn khôngphải do Microsoft cung cấp - sẽ thấy lỗi đó lặp lại giống hệt.Trở về với đoạn chương trình VB ban đầu, nếu đổi các biến a, b, s thành kiểu Currency thìchương trình lại chạy đúng như mong đợi (tức là đưa ra thông báo True). Dài dòng như vậyđể các bạn thấy gốc rễ của vấn đề nằm ở đặc điểm của số dấu chấm động nhị phân và các phéptoán liên quan tới chúng.Không ít lập trình viên chịu bó tay không lý giải được hiện tượng trên. Điều khá ngạc nhiên làcác số dấu chấm động hiện diện ở khắp mọi nơi trong các hệ thống máy tính vậy mà nhiều ngườivẫn không biết hay không quan tâm tới chúng. Hầu hết tất cả các ngôn ngữ lập trình đều có kiểudữ liệu dấu chấm động; các hệ thống điện toán từ máy PC đến siêu máy tính đều có bộ gia tốcdấu chấm động; hầu hết các trình biên dịch đều phải thực hiện việc dịch các thuật toán dấu chấmđộng một các thường xuyên và hầu như tất cả các hệ điều hành đều phải đối mặt với nhữngtrường hợp ngoại lệ của dấu chấm động (chẳng hạn bị tràn bộ nhớ).Một số dấu chấm động là cách biểu diễn cho một số trong một tập con các số hữu tỷ và thườngdùng trong máy tính để biểu diễn gần đúng một số thực bất kỳ. Một cách cụ thể hơn, số dấuchấm động được thể hiện như một số nguyên hay số dấu chấm tĩnh (phần có nghĩa hay phần địnhtrị) nhân với một cơ số (thường là cơ số 2 đối với máy tính) lũy thừa (số mũ) nguyên nào đó.a = m × beTrong một hệ thống như vậy, chúng ta chọn cơ số b và độ chính xác p (số chữ số được lưu). m(phần có nghĩa hay phần định trị) là một số có p chữ số được biểu diễn dưới dạng ±d.ddd...ddd(mỗi số là một số nguyên từ 0 đến b-1). Nếu số đầu tiên của m khác 0 thì nó được coi là đã chuẩnhóa. Một số cách mô tả có sử dụng một bit dấu riêng (s, thay thế cho -1 hoặc +1) và m buộc phảilà số dương, e được gọi là số mũ.Mô hình này cho phép biểu diễn một giải số khá lớn trong một số bit nhỏ mà cách biểu diễn dấuchấm tĩnh không thể hiện được. Ví dụ, một số dấu chấm động với 4 số phần thập phân (b = 10, p= 4) và số mũ trong khoảng ±4 có thể dùng để biểu diễn các số 43210, 4.321 hay 0.0004321,nhưng sẽ không đủ chính xác để biểu diễn cho số 432.123 và 43212.3 (và do đó sẽ được làm trònđến 432.1 và 43210). Trong thực tế số các chữ số thường lớn hơn 4.Ngoài ra, việc biểu diễn dấu chấm động thường bao gồm những giá trị đặc biệt: dương vô cực,âm vô cực và NaN (Not a Number - không phải số). Các giá trị vô cực được sử dụng khi kết quảquá lớn không thể biểu diễn được, còn NaN dùng để kết quả của những phép tính không hợp lệhoặc kết quả không được định nghĩa.Trong ví dụ trên, các con số được biểu diễn trong hệ thập phân (b = 10), hệ thống máy tính cũngthực hiện như vậy trong hệ nhị phân (b = 2). Trong máy tính, số dấu chấm động được xác địnhkích thước bằng số bit dùng để lưu trữ chúng. Kích thước này là 32 bit hoặc 64 bit, thường gọi làđộ chính xác đơn (single-precision) và độ chính xác kép (double-precision). Cũng có một số hệthống đưa ra những kích thước lớn hơn như 80 bit (dòng x86) hay 128 bit (thường được thựchiện bằng phần mềm). Bạn có thể xem cách biểu diễn dấu chấm động nhị phân của các số thậpphân tại trang web http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html.Thuật ngữ dấu chấm động xuất phát từ thực tế rằng không có số xác định các chữ số trước hoặcsau dấu chấm (dấu chấm thập phân có thể di chuyển được). Cách biểu diễn trong đó số các chữsố trước và sau dấu chấm thập phân cố định gọi là dấu chấm tĩnh. Nhìn chung, cách biểu diễnbằng dấu chấm động chậm hơn và thiếu chính xác hơn so với cách biểu diễn dấu chấm tĩnh,nhưng lại có thể biểu diễn được một vùng số lớn hơn.Một phép toán dấu chấm động là một phép toán số học được thực hiện với số dấu chấm động vàthường bao hàm cả phép tính gần đúng hay phép làm tròn bởi vì kết quả của một phép toán cóthể được biểu diễn một cách không chính xác. Do các phép toán với số dấu chấm động đòi hỏinhiều năng lực điện toán nên nhiều bộ vi xử lý thường đi kèm với một chip bổ sung FPU(floating point unit) chuyên dùng cho các phép toán dấu chấm động mà chúng ta thường gọi làbộ đồng xử lý toán học.RẮC RỐI SỐ DẤU CHẤM ĐỘNG NHỊ PHÂN1. Lỗi làm trònVì số dấu chấm động nhị phân không thể biểu diễn chính xác các số thập phân nên việc sử dụngchúng sẽ không thể đảm bảo cho kết quả như khi sử dụng các phép toán thập phân. Điều này gâyrất nhiều khó khăn cho việc phát triển và thử nghiệm các ứng dụng có sử dụng dữ liệu thực nhưthương mại hay tài chính. Dưới đây là một vài ví dụ điển hình.Lấy số 1 chia liên tục cho 10 sẽ cho kết quả như bảng dưới đây: Thập phân Nhị phân 0.1 0.1 0.01 0.01 0.001 9.999999E-4 0.0001 9.999999E-5 0.00001 9.999999E-6 0.000001 9.999999E-7 1E-7 9.999999E-8 1E-8 9.999999E-9 1E-9 9.999999E-10Cột bên trái hiển thị các kết quả mong đợi hay kết quả nhận được khi dùng BigDecimal class củaJava, cột bên phải hiển thị các kết quả nhận được bằng việc sử dụng kiểu dữ liệu float của Java.Các kết quả nhận được từ việc sử dụng kiểu dữ liệu do ...
Tìm kiếm theo từ khóa liên quan:
Kỹ thuật lập trình Phần cứng Công nghệ thông tin Tin học Quản trị mạngGợi ý tài liệu liên quan:
-
52 trang 430 1 0
-
24 trang 355 1 0
-
Top 10 mẹo 'đơn giản nhưng hữu ích' trong nhiếp ảnh
11 trang 314 0 0 -
74 trang 299 0 0
-
96 trang 293 0 0
-
Báo cáo thực tập thực tế: Nghiên cứu và xây dựng website bằng Wordpress
24 trang 289 0 0 -
Đồ án tốt nghiệp: Xây dựng ứng dụng di động android quản lý khách hàng cắt tóc
81 trang 281 0 0 -
EBay - Internet và câu chuyện thần kỳ: Phần 1
143 trang 275 0 0 -
Tài liệu dạy học môn Tin học trong chương trình đào tạo trình độ cao đẳng
348 trang 269 1 0 -
Kỹ thuật lập trình trên Visual Basic 2005
148 trang 265 0 0