Two Complements Python (with as least bits as possible)

2024/7/7 6:01:30

I am trying to output the binary representation of an negative number with the least bytes available each time.

Example:

-3 -> 101
-10 -> 10110
Answer

Here's a way to do this using the .bit_length method of Python 3 integers. It also uses the string .format method to do the integer to binary string conversion. This function returns a string starting with '0' for non-negative numbers so that they can be distinguished from negative numbers.

def twos_complement(n):m = n + 1 if n < 0 else nbitlen = 1 + m.bit_length()mask = (1 << bitlen) - 1return '{0:0{1}b}'.format(n & mask, bitlen)for i in (-10, -3, 0, 3, 10):print('{:3}: {}'.format(i, twos_complement(i)))print('- ' * 30)for i in range(-15, 16):print(i, twos_complement(i))    

output

-10: 10110-3: 1010: 03: 01110: 01010
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
-15 10001
-14 10010
-13 10011
-12 10100
-11 10101
-10 10110
-9 10111
-8 1000
-7 1001
-6 1010
-5 1011
-4 100
-3 101
-2 10
-1 1
0 0
1 01
2 010
3 011
4 0100
5 0101
6 0110
7 0111
8 01000
9 01001
10 01010
11 01011
12 01100
13 01101
14 01110
15 01111

How it works

Python uses a modified form of two's complement to represent integers. Python integers have no size limit, so negative integers behave as if they have an infinite number of leading 1 bits, as explained in the Python Wiki article on Bitwise Operators.

The int.bit_length method tells us the minimum number of bits required to represent a number, we want one more bit than that so that all our non-negative numbers will start with 0 and all the negative numbers start with a 1. We need to modify that slightly to ensure that numbers of the form -2**n will only get a single leading one bit, we do that by adding 1 to all the negative numbers when calculating the bit length.

To select the bits we want we need a bit mask of the appropriate length. If the bit length is 4, we want a mask of 1111 = 2**4 - 1; we _could calculate it by using exponentiation, but it's more efficient to use bit shifting: (1 << bitlen) - 1. We then do the bitwise AND operation n & mask to select the bits we want. Fortunately, Python gives us a non-negative number when we perform such masking operations. :)

Finally we convert the resulting integer to a string using the .format method. We use a nested format specification so we can dynamically specify the correct length of the output string. In

'{0:0{1}b}'.format(n & mask, bitlen) 

the first 0 of the format spec says that we're converting the value of the 0 arg in the argument list (n & mask), the :0{1}b says to convert it to binary, padded with leading zeroes if necessary, using the value of the 1 arg in the argument list (bitlen) as the total string length.

You can read about nested format specs in the Format String Syntax section of the docs:

A format_spec field can also include nested replacement fieldswithin it. These nested replacement fields may contain a field name,conversion flag and format specification, but deeper nesting is notallowed. The replacement fields within the format_spec aresubstituted before the format_spec string is interpreted. Thisallows the formatting of a value to be dynamically specified.

https://en.xdnf.cn/q/120377.html

Related Q&A

iterating through a column in dataframe and creating a list with name of the column + str

I have a dataframe with 2 coulmn, i want to iterate through the column headers, use that value and add a string to it and use it as the name of a list.rrresampled=pd.DataFrame() resampled[RAT]=dd1[RAT]…

Python multiple inheritance name clashes [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.Questions asking for code must demonstrate a minimal understanding of the problem being solved. Incl…

How to read multiple txt file from a single folder in Python? [duplicate]

This question already has answers here:How to open every file in a folder(8 answers)Closed 3 years ago.How can I read multiple txt file from a single folder in Python?I tried with the following code b…

Time Changing Without Clicking Button

The following code works fine as long as the time in the spinbox does not change. What I want is to do the set the time for a break. The first time it works perfectly but after that if I change the val…

Avoid `logger=logging.getLogger(__name__)` without loosing way to filter logs

I am lazy and want to avoid this line in every python file which uses logging:logger = logging.getLogger(__name__)In january I asked how this could be done, and found an answer: Avoid `logger=logging.g…

Find all directories and files of your laptop [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.Want to improve this question? Update the question so it focuses on one problem only by editing this post.Closed 8…

How to format and write excel using pandas

Lets assume that we have nested python dictionaries which should be written in single excel sheet file. Following are sample dictionaries which can be used. Car = [{"carbmodel": "Model A…

Openpyxl is unable to read after modifying

Requirement : 1.create a gui using Tkinter 2.Update the excel by fetching values from Tkinter entry widget 3.Read another sheet of the same workbook 4.plot graph using inside the Tkinter window.Prob…

Rounding datetime based on time of day

I have a pandas dataframe with timestamps shown below:6/30/2019 3:45:00 PMI would like to round the date based on time. Anything before 6AM will be counted as the day before. 6/30/2019 5:45:00 AM -&g…

Scraping Project Euler site with scrapy [closed]

Closed. This question needs debugging details. It is not currently accepting answers.Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to repro…