Số âm được biểu diễn bằng Python như thế nào?

Trong phần trước về biểu diễn và thao tác nhị phân, chúng ta chỉ thảo luận về số nguyên dương và số không. Số âm làm phức tạp mọi thứ một chút

Biểu diễn số nguyên âm

Chúng ta nên biểu diễn -1 ở dạng nhị phân như thế nào?

Dấu và độ lớn. Có vẻ như là một ý tưởng tốt vào thời điểm đó

Một cách tiếp cận đơn giản là đặt trước một chữ số nhị phân làm bit dấu. Ví dụ: trong số nguyên 8 bit, 10000001 có thể biểu thị -1 và 10000101 có thể biểu thị -5.
Đó gọi là biểu diễn dấu và độ lớn. Nó đơn giản, nhưng nó có một số vấn đề.

Trong biểu diễn dấu và độ lớn, chúng tôi kết thúc bằng 00000000 cho số không dương và 10000000 cho số không âm. Nhưng… thực sự, số 0 âm? . Và nó làm

Từ quan điểm của một nhà thiết kế máy tính, việc biểu diễn dấu và độ lớn làm tăng thêm rất nhiều sự phức tạp cho mạch điện cần thiết cho số học. Hãy xem xét điều đó bằng cách nào đó khi chúng ta thêm \(00000001_2\) (1) và \(10000001_2\) (-1) chúng ta sẽ nhận được \(00000000_2\) (0). Mạch cộng các số nguyên dương sẽ không làm được điều đó, vì vậy mạch có mục đích đặc biệt cho số học trên các số âm sẽ được yêu cầu. Các nhà thiết kế chip ghét điều đó

Một đại diện mà các nhà thiết kế chip có thể hài lòng với việc thêm ít phức tạp nhất có thể vào mạch CPU. Việc cộng một số âm với một số dương hoặc một số âm với một số âm sẽ hoạt động giống hệt như cộng hai số dương. Điều này đưa chúng ta đến ký hiệu bổ sung của hai

phần bù của hai. Một cách tốt hơn

Biểu diễn cho các số âm thực sự được sử dụng trong hầu hết các máy tính kỹ thuật số hiện đại là phần bù của hai. Trong ký hiệu này, biểu diễn 8 bit của -1 là 11111111 và biểu diễn 8 bit của 1 tất nhiên là 00000001. Nếu chúng ta thêm chúng, chúng ta sẽ “mang một” đến chữ số thứ 9 (không tồn tại), nơi nó bị mất và chúng ta nhận được 00000000. Phép cộng và phép trừ có thể thực hiện theo cách thông thường, không có trường hợp đặc biệt nào đối với số âm

Bản chất của biểu diễn bù hai là, trong khi giá trị của chữ số \(p\) thường là \(2^p\), thì giá trị của chữ số ngoài cùng bên trái là \(-2^p\)

Trong số nguyên có dấu 8 bit, bit 7 đại diện cho \(-(2^7)\) hoặc -128. Do đó, số 8 bit có dấu 10000110 là \(-(2^7) + 2^2 + 2^1\) = -128 + 4 + 2 = -122

Số âm được biểu diễn bằng Python như thế nào?

Chúng tôi đã nói ở trên rằng đại diện 8 bit của -1 sẽ là 11111111. Chúng ta có thể thấy rằng điều này là do bit ngoài cùng bên trái (vẫn được gọi là bit dấu) đại diện cho -128 và các bit còn lại đại diện cho 127, do đó, chúng cùng nhau đại diện cho -1

Kiểm tra việc hiểu của bạn

Nếu 11111111 là -1, biểu diễn của -2 là gì?

Phạm vi giá trị nào có thể được biểu thị bằng một số nguyên 8 bit bằng cách sử dụng ký hiệu bổ sung của hai?

Python 'bin' nói dối về số âm

Nếu bạn dựa vào hàm Python bin để kiểm tra biểu diễn nhị phân của số nguyên, bạn sẽ gặp sự cố. Hàm bin của Python sử dụng ký hiệu dấu và độ lớn, không phải phần bù hai, để biểu thị một số nguyên âm dưới dạng một chuỗi ký tự

x_masked = x & 0b111
x_shifted = x_masked << 3
w = w | x_shifted
0 và
x_masked = x & 0b111
x_shifted = x_masked << 3
w = w | x_shifted
1. Theo cách này, hàm Python bin luôn có thể tạo ra một chuỗi bắt đầu bằng ký tự
x_masked = x & 0b111
x_shifted = x_masked << 3
w = w | x_shifted
1, ngoại trừ giá trị nhị phân 0. Nó không cần hiển thị các số 0 đứng đầu trên một số nguyên dương và không cần hiển thị một chuỗi dài các ký tự
x_masked = x & 0b111
x_shifted = x_masked << 3
w = w | x_shifted
1 cho một số nguyên âm nhỏ

>>> bin(-1)
'-0b1'
>>> bin(-2)
'-0b10'

Điều này thường thuận tiện, đặc biệt khi xem xét biểu diễn bên trong thực của âm trong Python có khả năng bắt đầu với ít nhất 31 bit 1. Tuy nhiên, nó có thể gây hiểu lầm khi bạn đang cố gắng suy luận cẩn thận về biểu diễn thực tế của các số âm.

mở rộng dấu hiệu

Lưu ý rằng khi chúng ta mô tả biểu diễn của một số nhị phân âm, chúng ta cần cho biết có bao nhiêu bit trong biểu diễn. Biểu diễn của -1 dưới dạng số nguyên có dấu 8 bit là 11111111, nhưng biểu diễn của -1 dưới dạng số nguyên có dấu 16 bit là 1111111111111111. Tôi không muốn nhập biểu diễn của -1 dưới dạng số nguyên có dấu 32 bit hoặc dưới dạng số nguyên có dấu 64 bit, nhưng bạn có thể đoán nó trông như thế nào

Giả sử chúng ta có số nguyên có dấu 3 bit. Khi đó 101 đại diện cho \(-2^2 + 2^0\) = -4 + 1 = -3. Giả sử tôi muốn lưu trữ cùng một giá trị này trong một số nguyên có chữ ký 5 bit. Giá trị mới sẽ trở thành 11101, nghĩa là -16 + 8 + 4 + 1 = -3

Số âm được biểu diễn bằng Python như thế nào?

Bạn có thể thấy mô hình. Nếu chúng ta muốn lưu trữ một giá trị n-bit đã ký trong trường m-bit lớn hơn, chúng ta phải thêm 1 chữ số vào bên trái. Tổng quát hơn, những gì chúng ta đệm bằng là bit dấu. Do đó, số âm 3 bit 101 được đệm vào số âm 5 bit 11101, trong khi số dương 3 bit 011 được đệm vào số dương 5 bit 00011

Số âm được biểu diễn bằng Python như thế nào?

Điều này được gọi là mở rộng dấu hiệu

Nếu chúng ta đi theo cách khác, chúng ta chỉ cần cắt các bit ở bên trái, cho dù chúng là 0 hay 1. Nếu các bit chúng tôi cắt bỏ không giống nhau và giống với bit dấu còn lại, thì số đó không vừa với trường nhỏ hơn

Đóng gói và trích xuất các trường bit

Khi chúng ta đóng gói nhiều giá trị vào một số nguyên, chúng ta phải cẩn thận xác định xem giá trị đó có được hiểu là số nguyên có dấu trong đó bit ngoài cùng bên trái là bit dấu, biểu thị lũy thừa âm 2 hay một số nguyên không dấu trong đó tất cả các

Giả sử chúng ta sử dụng bốn bit, bit 0. 3, để đại diện cho một số nguyên. Chúng tôi có thể coi trường đó là một số nguyên không dấu có thể nằm trong khoảng từ 0 đến 15 hoặc chúng tôi có thể coi nó là một số nguyên có dấu có thể nằm trong khoảng từ -8 đến 7. Nếu chúng ta coi nó là một số nguyên không dấu, thì việc tạo mặt nạ và dịch chuyển có thể hoạt động chính xác như được mô tả trong chương trước, nhưng chúng ta không thể biểu diễn các giá trị âm. Nếu coi nó là số nguyên có dấu thì khi giải nén ta phải thêm bước mở rộng có dấu

Để đóng gói một giá trị đã ký vào một trường, chúng tôi không cần phải làm gì đặc biệt ngoại trừ đảm bảo che dấu giá trị để cắt bỏ bất kỳ bit 1 thừa nào ở bên trái. Ví dụ: nếu chúng tôi muốn lưu trữ giá trị 3 bit có dấu

x_masked = x & 0b111
x_shifted = x_masked << 3
w = w | x_shifted
5 trong bit 3. 5 của
x_masked = x & 0b111
x_shifted = x_masked << 3
w = w | x_shifted
0, giả sử các bit đó của
x_masked = x & 0b111
x_shifted = x_masked << 3
w = w | x_shifted
0 ban đầu bằng 0, chúng ta sẽ cần che dấu bất kỳ bit cao nào, như thế này

x_masked = x & 0b111
x_shifted = x_masked << 3
w = w | x_shifted

Chỉ khi trích xuất chúng ta mới phải thực hiện gia hạn dấu. Ví dụ: nếu

x_masked = x & 0b111
x_shifted = x_masked << 3
w = w | x_shifted
5 ở dòng trước là -1 và
x_masked = x & 0b111
x_shifted = x_masked << 3
w = w | x_shifted
0 là giá trị 8 bit 0, thì
x_masked = x & 0b111
x_shifted = x_masked << 3
w = w | x_shifted
0 sau đoạn mã trên sẽ chứa
x_masked = x & 0b111
x_shifted = x_masked << 3
w = w | x_shifted
5. Chúng tôi muốn trích xuất trường theo bit 3. 5, giữ giá trị
x_masked = x & 0b111
x_shifted = x_masked << 3
w = w | x_shifted
6, diễn giải lại là -1. Để làm điều đó, chúng ta phải mở rộng bit dấu (1 đầu tiên) cho dù phải điền từ mà chúng ta đang trích xuất trường đó bao xa.

Việc triển khai tiện ích mở rộng ký hiệu trong Python hơi kỳ quặc. Bạn phải hiểu tại sao và khi nào thực hiện gia hạn ký hiệu, nhưng tôi sẽ cung cấp chức năng mở rộng ký hiệu mà bạn có thể gọi

Tóm lược

Trong tất cả các máy tính kỹ thuật số hiện đại, các số nguyên âm được biểu diễn bằng hệ thống bổ sung của hai. Trong hệ thống này, bit dấu biểu thị lũy thừa âm của 2 và tất cả các bit khác biểu thị lũy thừa dương của 2

Ký hiệu bổ sung của hai rất thuận tiện và hiệu quả cho các nhà thiết kế chip, bởi vì số học với số âm và số dương hoạt động hoàn toàn giống nhau, không có mạch bổ sung

Khi chúng ta đóng gói nhiều số nguyên nhỏ thành một giá trị số nguyên, chúng ta phải cẩn thận về việc chúng ta dự định một trường đại diện cho giá trị có dấu hay giá trị không dấu. Nếu trường đại diện cho một giá trị không dấu, thì mỗi bit \(p\) đại diện cho \(2^p\). Một giá trị không dấu với các bit \(k\) nằm trong khoảng từ \(0\) đến \(2^k-1\).
Nếu trường đại diện cho một giá trị đã ký, thì bit dấu đại diện cho \(-2^p\) và tất cả các bit khác \(p\) đại diện cho \(2^p\).

Khi chúng tôi đóng gói một giá trị đã ký vào một trường nhỏ hơn, chúng tôi sẽ che đi bất kỳ bit 1 thừa nào ở bên trái. Khi chúng tôi trích xuất một giá trị có dấu vào một từ bộ nhớ lớn hơn, chúng tôi phải ký mở rộng nó, lấp đầy tất cả các bit ở bên trái của bit dấu của trường nhỏ hơn bằng các bản sao của bit dấu

Khi chúng tôi sử dụng hàm Python bin, chúng tôi nhận được biểu diễn chuỗi dựa trên ký hiệu dấu và độ lớn chứ không phải là biểu diễn chính xác của biểu diễn phần bù hai bên trong thực tế

Làm thế nào để Python nhận ra số âm?

Mã Python. n = float(input("Nhập một số. ")) nếu n >= 0. nếu n == 0. print("Đó là số 0. ") khác. print("Số là số dương. ") khác. print("Số là số âm. ")

Số âm được biểu diễn như thế nào?

Số âm thường được viết với dấu trừ phía trước . Ví dụ: −3 đại diện cho một đại lượng âm có độ lớn bằng ba và được phát âm là "trừ ba" hoặc "âm ba".

Số âm có đúng trong Python không?

Trong Python, số nguyên 0 luôn là Sai, trong khi mọi số khác, kể cả số âm, đều là Đúng . Trên thực tế, bool eans kế thừa từ int eger.