Programmer's Python Data - Bits and BigNum
Written by Mike James   
Monday, 25 March 2024
Article Index
Programmer's Python Data - Bits and BigNum
The Bitwise Operators
NOT

NOT

The action of the bitwise NOT operator is very simple – it inverts all of the bits, setting ones to zeros and zeros to ones:

a
~a

0

1

1

0

Simple though that seems, the way that Python uses bignums to represent bit patterns presents two different problems. The first is, knowing how many leading zeros the input bit pattern has. In other languages bit patterns are always a fixed size – usually 32 or 64 bits. When you use the NOT operator on a bit pattern all of the bits are inverted. So if you write:

a = x0F
b = ~a

and there are 32 bits, the result in b is:

0xFFFFFFF0

You can see that the value stored in a has been treated as if it was:

0x0000000F

In the case of Python, however, with no fixed number of bits there are an arbitrary number of leading zeros and so the result could be:

0x...FFFFFFFFFFFFFFFFFFFFFFFFFFF0

where the … means as many bits as available memory allows.

To avoid this Python only uses as many bits as necessary to represent the value and a single leading zero as the sign bit. As in the case of a general bitwise operation, the sign bit is extended to match the largest of the bit patterns involved.

What this means is that:

a = 0x0F
print(~a )

displays a result of -16. The reason is that the bit pattern stored in a is 1111 which is converted to 0 1111 with the sign bit of zero signifying a positive number. Next the bits, including the sign bit, are inverted to give 1 0000 which is -16 in two's complement form. If you try to print this in binary then you get the result:

-0b10000

which is probably not what you are expecting but, due to the conversion to two's complement, does give you the bit pattern you expect if you make use of it. That is, -0b10000 behaves like 0b0, apart from the sign bit which you can usually ignore. Each time the value in a bignum is converted to two’s complement and then back to signed magnitude representation. So, as long as you don’t examine the value in the bignum, everything works as if you were working with a two's complement bit pattern.

Included in the chapter but not in this extract

  • Masks
  • Using Masks
  • Shifting Values
  • Testing a Bit
  • Bit Manipulation and Arithmetic
  • Bit Manipulation As Art

Summary

  • The fundamental data entity is the bit pattern and it is up to the program and programmer to assign a meaning to any particular bit pattern.

  • Hexadecimal (hex) makes specifying a bit pattern easier as each hex symbol corresponds to four binary bits.

  • Number bases that are a power of 2 have the property that they are easier to convert to binary. The other base that is useful is octal which specifies three bits per symbol.

  • The fact that Python uses unlimited precision integers, bignums, makes working with bit patterns different to the usually encountered fixed width bit patterns which are typically 16, 32 or 64 bits in size.

  • The bitwise operators &, |, ^, ~ perform logical operations on pairs of bits.

  • Negative numbers are a problem for bitwise operations because bignums are stored in sign-value representation and bitwise operations generally use two's complement representation.

  • You cannot create a negative bignum using a binary value because you cannot set the sign bit. The only way is to use a negative sign.

  • The not ~ operator is particularly difficult to understand unless you think of it as creating additional sign bits that are then trimmed back to a single sign bit.

  • It is helpful to think in terms of masks to set and unset particular bits in a bit pattern.

  • You can use a mask approach to testing if particular bits in a pattern are a zero or a one.

  • The shift operators << and >> shift the bit pattern to the left and right. Left shifts move zeros into the left and right shift moves a copy of the sign bit into the most significant bit.

  • An alternative to using logical bitwise operations is to use arithmetic. This is usually harder to understand, but it has the advantage of working in other number bases.

  • Bit manipulation is an art form and you can spend many hours trying to find a clever and efficient way of doing any task.

Programmer's Python
Everything is Data

Is now available as a print book: Amazon

pythondata360Contents

  1. Python – A Lightning Tour
  2. The Basic Data Type – Numbers
       Extract: Bignum
  3. Truthy & Falsey
  4. Dates & Times
       Extract Naive Dates ***NEW!!!
  5. Sequences, Lists & Tuples
       Extract Sequences 
  6. Strings
       Extract Unicode Strings
  7. Regular Expressions
  8. The Dictionary
       Extract The Dictionary 
  9. Iterables, Sets & Generators
       Extract  Iterables 
  10. Comprehensions
       Extract  Comprehensions 
  11. Data Structures & Collections
       Extract Stacks, Queues and Deques
      
    Extract Named Tuples and Counters
  12. Bits & Bit Manipulation
       Extract Bits and BigNum 
  13. Bytes
       Extract Bytes And Strings
       Extract Byte Manipulation 
  14. Binary Files
  15. Text Files
  16. Creating Custom Data Classes
        Extract A Custom Data Class 
  17. Python and Native Code
        Extract   Native Code
    Appendix I Python in Visual Studio Code
    Appendix II C Programming Using Visual Studio Code

<ASIN:1871962765>

<ASIN:1871962749>

<ASIN:1871962595>

<ASIN:B0CK71TQ17>

<ASIN:187196265X>

Related Articles

Creating The Python UI With Tkinter

Creating The Python UI With Tkinter - The Canvas Widget

The Python Dictionary

Arrays in Python

Advanced Python Arrays - Introducing NumPy

espbook

 

Comments




or email your comment to: comments@i-programmer.info

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner



Last Updated ( Tuesday, 26 March 2024 )