INT_MIN-1 là dòng chảy tràn hay tràn?


10

Tôi dường như nhớ rằng tôi đã đọc nó

  • underflowcó nghĩa là bạn có một cường độ quá nhỏ không thể trình bày được nữa trong một loại
  • overflowcó nghĩa là bạn có một cường độ quá lớn không thể được trình bày trong một loại

Tuy nhiên, trong thực tế tôi nhận thấy rằng các thuật ngữ được sử dụng sao cho

  • underflowcó nghĩa là bạn có một giá trị quá nhỏ không thể trình bày được nữa trong một loại
  • overflowcó nghĩa là bạn có một giá trị quá lớn không thể trình bày được nữa trong một loại

Ý nghĩa chính xác để sử dụng ở đây là gì? Các thuật ngữ được định nghĩa khác nhau cho các loại số nguyên và dấu phẩy động?


2
Nói chung, thuật ngữ "dòng chảy" dường như được dành riêng cho số học dấu phẩy động. Với số nguyên, tôi thường nói "tràn" bất kể đó là INT_MIN - 1hayINT_MAX + 1
Charles Salvia

Câu trả lời:


15

Tôi thực sự không thể tìm thấy một nguồn "có thẩm quyền" về vấn đề này, chủ yếu là vì đây có lẽ là vấn đề quy ước và thuật ngữ thường không nhất quán. Nhưng, đoạn trích sau đây từ " Mã hóa an toàn trong C và C ++ " của Robert Seacord đã tóm tắt sự hiểu biết của tôi về tình huống này:

Một tràn số nguyên xảy ra khi một số nguyên được tăng vượt quá giá trị tối đa của nó hoặc giảm vượt quá giá trị tối thiểu 3 của nó . Tràn số nguyên có liên quan chặt chẽ với biểu diễn bên dưới.

Các chú thích tiếp tục nói:

[3] Giảm một số nguyên vượt quá giá trị tối thiểu của nó thường được gọi là một số nguyên underflow , mặc dù về mặt kỹ thuật ngữ này dùng để chỉ một tình trạng dấu chấm động.

Lý do chúng tôi gọi nó là tràn số nguyên là vì không có đủ không gian có sẵn trong loại để thể hiện giá trị. Theo nghĩa đó, nó tương tự như tràn bộ đệm (ngoại trừ thay vì thực sự vượt qua ranh giới bộ đệm, nó thường thể hiện hành vi bao quanh. *) Từ quan điểm này, không có sự khác biệt về khái niệm giữa INT_MIN - 1INT_MAX + 1. Trong cả hai trường hợp, đơn giản là không có đủ không gian trong intloại dữ liệu để biểu thị một trong hai giá trị - vì vậy những gì chúng ta có là một tràn .

Cũng có thể hữu ích khi lưu ý rằng trong kiến ​​trúc bộ xử lý x86 và x86_64, thanh ghi cờ bao gồm một bit tràn . Bit tràn được thiết lập khi hoạt động số học số nguyên đã ký tràn. Biểu thức INT_MIN - 1sẽ đặt bit tràn. (Không có bit "underflow".) Vì vậy, rõ ràng, các kỹ sư của AMD và Intel sử dụng thuật ngữ "tràn" để mô tả kết quả của một phép toán số nguyên có quá nhiều bit phù hợp với kiểu dữ liệu, bất kể là giá trị số quá lớn hoặc quá nhỏ.


* Trong thực tế, trong C, tràn số nguyên đã ký thực sự là hành vi không xác định, nhưng trong các ngôn ngữ khác như Java, số học bổ sung của hai sẽ bao quanh.


6

Đó là một tràn. Một dòng không xảy ra cho các giá trị số nguyên.

Một tràn là khi một giá trị quá lớn (quá xa từ 0) được biểu thị bằng loại cụ thể và một dòng dưới là khi nó quá nhỏ (quá gần bằng 0).

Vì các giá trị số nguyên gần nhất bằng 0 (1 và -1) vẫn có thể được biểu diễn bằng bất kỳ biến số nguyên nào (giả sử một số nguyên có chữ ký có nhiều hơn một bit), không thể xảy ra một dòng chảy bên dưới.

Các bài viết trên Wikipedia về underflow có một mô tả khá rõ ràng:

"Thuật ngữ dòng chảy số học (hoặc" dòng chảy dấu phẩy động "hoặc chỉ là" dòng chảy ") là một điều kiện trong một chương trình máy tính có thể xảy ra khi kết quả thực sự của một phép toán dấu phẩy động có độ lớn nhỏ hơn (nghĩa là gần bằng 0) so với giá trị nhỏ nhất có thể biểu thị như một số dấu phẩy động thông thường trong kiểu dữ liệu đích. Một phần có thể được coi là tràn âm của số mũ của giá trị dấu phẩy động. "


Có thể hữu ích khi lưu ý rằng underflowthường được sử dụng cụ thể để chỉ điều kiện cụ thể trong đó cường độ của một số nhỏ hơn giá trị khác không nhỏ nhất có thể, nhưng lớn hơn khoảng cách nhỏ nhất có thể giữa các giá trị khác không - khác từ, trường hợp số rơi vào bài viết Wiki gọi là "khoảng cách dòng chảy". Trên các triển khai tuân thủ theo chuẩn IEEE-744, số có thể biểu thị nhỏ nhất bằng với chênh lệch có thể biểu thị nhỏ nhất giữa các số, do đó, các dòng chảy như vậy không thể xảy ra, nhưng bên ngoài thế giới PC, không phải tất cả các hệ thống đều tuân thủ theo chuẩn IEEE.
supercat

2

Trong toán học số nguyên, tràn chỉ các giá trị quá lớn và quá nhỏ. Trong dấu phẩy động, tràn liên quan đến số mũ quá lớn và dòng chảy liên quan đến số mũ quá nhỏ.

Trong thực tế, đối với các loại số nguyên , CPU không có cách nào để phân biệt sự khác biệt giữa tràn và tràn. Lấy phần bổ sung 16 bit sau:

  0x8000 (unsigned 32768, or signed -32767)
+ 0xFFFF (unsigned 65535, or signed -1)
--------
  0x7FFF (32767, the carried '1' is lost)

Tất nhiên, cờ tràn trong CPU sẽ được đặt sau lần thêm này. Sử dụng toán đã ký, kết quả quá nhỏ (-32768). Sử dụng toán không dấu, kết quả quá lớn (0x17FFF). Vì toán học bổ sung của 2 giống hệt nhau cho các loại đã ký và không dấu, nên overflowbuộc phải có nghĩa là cả hai giá trị quá lớn và quá nhỏ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.