Bạn hiện đang ngoại tuyến, hãy chờ internet để kết nối lại

(Hoàn thành) Hướng dẫn để hiểu IEEE Floating-Point lỗi

QUAN TRỌNG: Bài viết này được dịch bằng phần mềm dịch máy của Microsoft chứ không phải do con người dịch. Microsoft cung cấp các bài viết do con người dịch và cả các bài viết do máy dịch để bạn có thể truy cập vào tất cả các bài viết trong Cơ sở Kiến thức của chúng tôi bằng ngôn ngữ của bạn. Tuy nhiên, bài viết do máy dịch không phải lúc nào cũng hoàn hảo. Loại bài viết này có thể chứa các sai sót về từ vựng, cú pháp hoặc ngữ pháp, giống như một người nước ngoài có thể mắc sai sót khi nói ngôn ngữ của bạn. Microsoft không chịu trách nhiệm về bất kỳ sự thiếu chính xác, sai sót hoặc thiệt hại nào do việc dịch sai nội dung hoặc do hoạt động sử dụng của khách hàng gây ra. Microsoft cũng thường xuyên cập nhật phần mềm dịch máy này.

Nhấp chuột vào đây để xem bản tiếng Anh của bài viết này:42980
Khước từ Nội dung trong Cơ sở Kiến thức Không còn được hỗ trợ
Bài viết này nói về các sản phẩm mà Microsoft không còn hỗ trợ nữa. Do đó, bài viết này được cung cấp "nguyên bản" và sẽ không được cập nhật.
TÓM TẮT
Dấu chấm động toán học là một chủ đề phức tạp confuses nhiềucác lập trình viên. Các hướng dẫn dưới đây sẽ giúp bạn nhận ra lập trìnhtình huống nơi lỗi dấu chấm động có khả năng xảy ra và làm thế nào đểtránh cho họ. Nó cũng nên cho phép bạn để nhận ra được các trường hợpdo hạn chế vốn có dấu chấm động toán như trái ngược vớithực tế biên dịch lỗi.
THÔNG TIN THÊM

Thập phân và hệ thống số nhị phân

Thông thường, chúng tôi truy cập những thứ trong căn cứ 10. Cơ sở là hoàn toàntùy ý. Lý do chỉ có người dân có truyền thống sử dụng căn cứ10 là họ có 10 ngón tay, khiến có tiện dụng đếmcông cụ.

Số 532.25 trong thập phân (10 cơ sở) có nghĩa là sau đây:
   (5 * 10^2) + (3 * 10^1) + (2 * 10^0) + (2 * 10^-1) + (5 * 10^-2)       500    +     30     +      2     +     2/10    +    5/100   _________   =  532.25				

Trong số hệ đôi (cơ sở 2), mỗi cột đại diện cho một quyền lực2 thay vì của 10. Ví dụ, một số 101.01 có nghĩa là cácsau:
   (1 * 2^2) + (0 * 2^1) + (1 * 2^0) + (0 * 2^-1) + (1 * 2^-2)       4     +      0    +     1     +      0     +    1/4   _________   =  5.25  Decimal				

Làm thế nào số nguyên được đại diện trong các máy tính

Vì không có một phần phân đoạn để một số nguyên, máy của nóđại diện là đơn giản hơn nhiều so với nó là giá trị dấu chấm động. Normalsố nguyên trên máy tính cá nhân (PC) là 2 byte (16 bit) dài với cácbit quan trọng nhất cho thấy các dấu hiệu. Lâu dài nguyên là 4 byte dài.Giá trị tích cực là đơn giản số nhị phân. Ví dụ:
    1 Decimal = 1 Binary    2 Decimal = 10 Binary   22 Decimal = 10110 Binary, etc.				

Tuy nhiên, số nguyên âm được đại diện bằng cách sử dụng của hai bổ ngữđề án. Để có được của hai bổ sung đại diện cho một tiêu cựcsố, mất nhị phân đại diện cho một số giá trị tuyệt đốivà sau đó lật tất cả các bit và thêm 1. Ví dụ:
   4 Decimal = 0000 0000 0000 0100               1111 1111 1111 1011     Flip the Bits   -4        = 1111 1111 1111 1100     Add 1				

Lưu ý rằng -1 thập phân = 1111 1111 1111 1111 trong hệ nhị phân, mà giải thíchlý do tại sao Basic xử lý -1 là hợp lý đúng (tất cả các bit = 1). Đây là mộthậu quả của việc không có nhà khai thác riêng biệt cho bit và hợp lýso sánh. Thường trong Basic, rất thuận tiện để sử dụng đoạn mãdưới đây khi chương trình của bạn sẽ làm cho nhiều so sánh hợp lý. Điều nàyrất nhiều viện trợ dễ đọc.
   CONST TRUE = -1   CONST FALSE = NOT TRUE				

Lưu ý rằng việc thêm bất kỳ sự kết hợp của hai bổ sung cho số với nhaubằng cách sử dụng bình thường nhị phân cấp hàng số sản xuất kết quả chính xác.

Dấu chấm động biến chứng

Mỗi số nguyên thập phân có thể được chính xác được đại diện bởi một số nguyên dương nhị phân;Tuy nhiên, điều này là không đúng cho các con số phân đoạn. Trong thực tế, mỗisố lượng là chưa hợp lý trong cơ sở 10 cũng sẽ được chưa hợp lý trong bất kỳhệ thống với một cơ sở nhỏ hơn 10.

Cho nhị phân, trong đó, phân đoạn chỉ số có thểđại diện trong mẫu p/q, nơi q là một số nguyên sức mạnh của 2, có thểbày tỏ sự chính xác, với một số hữu hạn các bit.

Thậm chí phổ biến liên phân số thập phân, chẳng hạn như 0,0001 thập phân, không thểđại diện chính xác trong hệ nhị phân. (0,0001 là một lặp lại nhị phân phầnvới một khoảng thời gian của 104 bit!)

Điều này giải thích lý do tại sao một ví dụ đơn giản, chẳng hạn như sau
   SUM = 0   FOR I% = 1 TO 10000      SUM = SUM + 0.0001   NEXT I%   PRINT SUM                   ' Theoretically = 1.0.				

sẽ in 1.000054 như sản lượng. Lỗi nhỏ trong đại diện cho 0,0001trong hệ nhị phân Lan truyền với tổng.

Đối với lý do đó, bạn nên luôn luôn rất thận trọng khi thực hiệnso sánh về số thực. Ví dụ sau minh hoạ mộtlỗi lập trình phổ biến:
   item1# = 69.82#   item2# = 69.20# + 0.62#   IF item1# = item2# then print "Equality!"				

Điều này sẽ không in "sự bình đẳng!" bởi vì 69.82 không thể được đại diệnchính xác trong hệ nhị phân, mà nguyên nhân giá trị mà kết quả từ cácchuyển nhượng là hơi khác nhau (trong hệ nhị phân) so với giá trị nhỏđược tạo ra từ các biểu hiện. Trong thực tế, bạn nên luôn luôn mã sốso sánh như vậy theo cách cho phép cho một số dung sai. ChoVí dụ:
   IF (item1# < 69.83#) AND (item1# > 69.81#) then print "Equal"				

Điều này sẽ in "Bằng".

IEEE định dạng số

QuickBasic cho MS-DOS, phiên bản 3.0 đã được vận chuyển với một MBFPhiên bản (Microsoft đôi nổi điểm) và một IEEE (việnĐiện và điện tử kỹ sư) Phiên bản cho máy với mộtcoprocessor toán. QuickBasic cho MS-DOS, phiên bản 4.0 và sau nàychỉ sử dụng IEEE. Microsoft đã chọn các tiêu chuẩn IEEE để đại diện chofloating-point giá trị trong phiên bản hiện tại của cơ bản đối với các chi tiếtba lý do chính:
  1. Để cho phép cơ bản để sử dụng Intel toán coprocessors, sử dụng IEEE định dạng. Intel 80 x 87 loạt coprocessors không thể làm việc với Microsoft định dạng nhị phân số.
  2. Để làm cho interlanguage gọi giữa Basic, C, Pascal, FORTRAN, và MASM dễ dàng hơn nhiều. Nếu không, công việc chuyển đổi sẽ phải được sử dụng để gửi các giá trị số từ một ngôn ngữ khác.
  3. Để đạt được nhất quán. IEEE là tiêu chuẩn cho công nghiệp được chấp nhận Trình biên dịch c và FORTRAN.
Dưới đây là một so sánh nhanh chóng của IEEE và MBF đại diệnĐối với một số đôi chính xác:
               Sign Bits   Exponent Bits   Mantissa Bits               ---------   -------------   -------------   IEEE        1           11              52 + 1 (Implied)    MBF        1            8              56				

Cho biết thêm thông tin về sự khác nhau giữa IEEE và MBFdấu chấm động đại diện, truy vấn trong cơ sở kiến thức Microsoft ngàycác từ sau đây:
   IEEE and floating and point and appnote				

Lưu ý rằng IEEE có thêm bit dành riêng cho số mũ, cho phépnó đại diện cho một phạm vi rộng hơn của các giá trị. MBF có bộ mantissa bit,cho phép nó để chính xác hơn trong phạm vi hẹp hơn.

Tổng quát khái niệm dấu chấm động

Nó là rất quan trọng để nhận ra rằng bất kỳ hệ thống nhị phân, dấu chấm độngcó thể đại diện cho chỉ là một số hữu hạn các giá trị dấu chấm động trong chính xáchình thức. Tất cả các giá trị khác phải được ước chừng bằng gần nhấtgiá trị USD. IEEE tiêu chuẩn xác định phương pháp cholàm tròn các giá trị với giá trị USD "gần". QuickBasicĐối với MS-DOS hỗ trợ các tiêu chuẩn và các vòng Theo điều của IEEEquy tắc.

Ngoài ra, hãy nhớ rằng những con số có thể được biểu diễn trong IEEEđang lan rộng trên một phạm vi rất rộng. Bạn có thể tưởng tượng họ vào mộtsố dòng. Đó là một mật độ cao của các con số USD gần 1.0và-1.0 nhưng ít hơn và ít hơn như bạn đi theo hướng 0 hoặc vô cực.

Mục đích của các tiêu chuẩn IEEE, được thiết kế cho kỹ thuậttính toán, là để tối đa hóa độ chính xác (để có được càng gần càng tốt đểcon số thực tế). Dùng chính xác để chỉ số chữ số mà bạncó thể đại diện cho. Tiêu chuẩn IEEE cố gắng để cân bằng số lượngbit dành riêng cho số mũ với số bit được sử dụng cho cácmột phần phân đoạn của số, để giữ cho độ chính xác và độ chính xáctrong giới hạn chấp nhận được.

IEEE chi tiết

Các con số dấu chấm động được đại diện trong các hình thức sau đây, nơi[số mũ] là số mũ nhị phân:
   X =  Fraction * 2^(exponent - bias)				

[Phần nhỏ] là một phần phân đoạn bình thường của số, được chuẩn hoábởi vì số mũ được điều chỉnh để cho bit hàng đầu luôn luôn là một1. Này bằng cách nào, nó không phải được lưu trữ, và bạn có được một chút thêmcủa chính xác. Đây là lý do tại sao đó là một chút ngụ ý. Bạn có thể nghĩ đếnĐiều này giống như khoa học ký hiệu, nơi bạn thao tác số mũ đểcó một chữ số bên trái của điểm thập phân, ngoại trừ trong hệ nhị phân, bạnluôn luôn có thể thao tác số mũ vì vậy mà bit đầu tiên là một 1, từ đókhông có duy nhất 1 và 0s.

[thiên vị] là giá trị bias được sử dụng để tránh việc phải lưu trữ tiêu cựcsố mũ.

Xu hướng cho đĩa đơn chính xác số là 127 và 1023 (thập phân) chocác con số chính xác kép.

Các giá trị bằng 0 tất cả và tất cả của 1 (nhị phân) được dành riêng chođại diện cho trường hợp đặc biệt. Có những trường hợp đặc biệt khác là tốt,mà chỉ ra điều kiện lỗi khác nhau.

Single-Precision ví dụ

2 = 1 * 2 ^ 1 = 0100 0000 0000 0000... 0000 0000 = 4000 0000 hex
Lưu ý dấu hiệu chút là zero, và được lưu trữ số mũ là 128, hoặc 100 0000 0 trong hệ nhị phân, mà là 127 cộng với 1. Mantissa được lưu trữ là (1.) 000 0000... 0000 0000, trong đó có một ngụ ý hàng đầu 1 và nhị phân điểm, do đó, thực tế mantissa là 1.

-2 = -1 * 2 ^ 1 = 1100 0000 0000 0000... 0000 0000 = C000 0000 hex
Tương tự như + 2 trừ là dấu hiệu bit được thiết lập. Điều này là đúng cho tất cả IEEE định dạng dấu chấm động số điện thoại.

4 = 1 * 2 ^ 2 = 0100 0000 1000 0000... 0000 0000 = 4080 0000 hex
Mantissa cùng, số mũ tăng một (giá trị thiên vị là 129, hoặc 100 0000 1 trong hệ nhị phân.

6 = 1,5 * 2 ^ 2 = 0100 0000 1100 0000... 0000 0000 = 40 C 0 0000 hex
Cùng một số mũ, mantissa là lớn hơn một nửa - nó là (1.) 100 0000... 0000 0000, mà, vì đây là một đôi phần nhỏ, là 1-1/2 (các giá trị của chữ số phân đoạn là 1/2, 1/4, 1/8, v.v..).

1 = 1 * 2 ^ 0 = 0011 1111 1000 0000... 0000 0000 = 3F80 0000 hex
Cùng một số mũ như các quyền hạn của 2, mantissa là một trong ít hơn 2 127, hoặc 011 1111 1 trong hệ nhị phân.

.75 = 1,5 * 2 ^ -1 = 0011 1111 0100 0000... 0000 0000 = 3F40 0000 hex
Số mũ thiên vị là 126, 011 1111 0 trong nhị phân, và mantissa là (1.) 100 0000... 0000 0000, đó là 1-1/2.

2.5 = 1,25 * 2 ^ 1 = 0100 0000 0010 0000... hex 0000 0000 0000 = 4020
Chính xác giống như 2 ngoại trừ rằng bit mà đại diện cho 1/4 là thiết lập trong mantissa.

0,1 = 1.6 * 2 ^ -4 = 0011 1101 1100 1100... 1100 1101 = 3DCC CCCD hex
1/10 là một phần nhỏ trong lặp lại trong hệ nhị phân. Mantissa là chỉ nhút nhát của 1.6, và số mũ thành kiến nói rằng 1,6 để được chia cho 16 (nó là 011 1101 1 trong hệ nhị phân, mà là 123 trong thập phân). Sự thật số mũ là 123-127 = - 4, có nghĩa là các yếu tố mà nhân là 2 ** -4 = 1/16. Lưu ý rằng mantissa được lưu trữ làm tròn lên trong bit cuối cùng. Đây là một nỗ lực để đại diện cho các unrepresentable số chính xác càng tốt. (Lý do mà 1/10 và 1/100 là không chính xác USD trong hệ nhị phân là tương tự như cách 1/3 là không chính xác USD trong thập phân.)

0 = 1.0 * 2 ^-128 = tất cả các Zero - một trường hợp đặc biệt.

Lỗi dấu chấm động phổ biến khác

Sau đây là lỗi dấu chấm động phổ biến:
  1. Vòng tắt lỗi

    Lỗi này kết quả khi tất cả các bit trong một số nhị phân không thể được sử dụng trong tính toán một.

    Ví dụ: Thêm 0,0001 để 0.9900 (đơn chính xác)

    Thập phân 0,0001 sẽ được đại diện như:
    (1.) 10100011011011100010111 * 2^(-14+Bias) (13 dẫn 1s trong Binary!)
    0.9900 sẽ được đại diện như:
    (1.) 11111010111000010100011 * 2^(-1+Bias)
    Bây giờ thực sự thêm những con số này, các điểm (nhị phân) thập phân phải được liên kết. Đối với điều này, họ phải Unnormalized. Dưới đây là các bổ sung kết quả:
           .000000000000011010001101 * 2^0  <- Only 11 of 23 Bits retained      +.111111010111000010100011 * 2^0      ________________________________       .111111010111011100110000 * 2^0						
    Điều này được gọi là một vòng ra lỗi bởi vì một số máy tính vòng khi chuyển cho bổ sung. Những người khác chỉ đơn giản là truncate. Vòng tắt lỗi là quan trọng để xem xét bất cứ khi nào bạn đang thêm hoặc nhân hai giá trị rất khác nhau.
  2. Subtracting hai gần như bằng các giá trị
           .1235      -.1234       _____       .0001						
    Điều này sẽ được chuẩn hoá. Lưu ý rằng mặc dù những con số gốc mỗi người có bốn chữ số quan trọng, kết quả đã chỉ có một chữ số đáng kể.
  3. Tràn và underflow

    Điều này xảy ra khi kết quả là quá lớn hoặc quá nhỏ để đại diện bởi kiểu dữ liệu.
  4. Quantizing lỗi

    Điều này xảy ra với những con số mà không thể được đại diện trong chính xác hình thức bởi các tiêu chuẩn dấu chấm động.
  5. Bộ phận của một số lượng rất nhỏ

    Điều này có thể kích hoạt một lỗi "phân chia bởi zero" hoặc có thể sản xuất xấu kết quả, như trong ví dụ sau:
          A = 112000000      B = 100000      C = 0.0009      X = A - B / C						
    Trong QuickBasic cho MS-DOS, X bây giờ có giá trị 888887, thay vì câu trả lời đúng, 900000.
  6. Đầu ra lỗi

    Loại lỗi xảy ra khi thay đổi các chức năng sản lượng các giá trị họ đang làm việc với.
1,00 2,00 3.00 4,00 4.00b 4.50 6,00 6.00b 7,00 7,10 IEEETUTR

Cảnh báo: Bài viết này đã được dịch tự động

Thuộc tính

ID Bài viết: 42980 - Xem lại Lần cuối: 08/17/2011 14:28:00 - Bản sửa đổi: 2.0

Microsoft Visual Basic 2.0 Standard Edition, Microsoft Visual Basic 3.0 Professional Edition, Microsoft Visual Basic 1.0 Standard Edition, Microsoft Visual Basic 2.0 Professional Edition, Microsoft BASIC Professional Development System 7.0

  • kbmt KB42980 KbMtvi
Phản hồi