Apa itu shift kiri dan shift kanan di python?

Bitwise Right shift operator >> digunakan untuk menggeser urutan biner ke sisi kanan dengan posisi yang ditentukan


Contoh

Mari kita ambil nomor 14

Representasi biner dari 14 adalah 00001110 (demi kejelasan mari kita tulis menggunakan 8 bit)

14 = (00001110) 2

Maka 14 >> 1 akan menggeser barisan biner sebanyak 1 posisi ke sisi kanan

Suka,

Penjelasan Bergambar

Apa itu shift kiri dan shift kanan di python?




Penerapan Operator Pergeseran Kanan Bitwise

Pada diagram di atas, Anda dapat melihat bahwa setiap kali kita menggeser posisi nomor satu ke kanan, nilai keluarannya akan persis seperti angka / 2

Jika saya menggeser 14 dengan 1 posisi ke kanan, hasilnya adalah 14/2 = 7. saya. dan 14/2 = 7

Jika saya menggeser 14 dengan 2 posisi ke kanan, hasilnya adalah 14/4 = 3. saya. dan 14/4 =3. 5 karena bilangan bulat, bagian pecahan tidak akan dipertimbangkan

Bitwise Operator shift kiri digunakan untuk menggeser urutan biner ke sisi kiri dengan posisi yang ditentukan

Contoh

Mari kita ambil nomor 14

Representasi biner dari 14 adalah 00001110 (demi kejelasan mari kita tulis menggunakan 8 bit)

14 = (00001110) 2

Maka 14 << 1 akan menggeser posisi barisan biner 1 ke sisi kiri

Suka,

Penjelasan Bergambar

Apa itu shift kiri dan shift kanan di python?




Penerapan Operator Pergeseran Kiri Bitwise

Pada diagram di atas, Anda dapat melihat bahwa setiap kali kita menggeser posisi nomor satu ke kiri, nilai keluarannya akan persis seperti angka * 2

Operator pergeseran bitwise memindahkan nilai bit dari objek biner. Operan kiri menentukan nilai yang akan digeser. Operan kanan menentukan jumlah posisi bit dalam nilai yang akan digeser. Hasilnya bukan nilai. Both operands have the same precedence and are left-to-right associative

OperatorUsage<>Indicates the bits are to be shifted to the right.

Each operand must have an integral or enumeration type. The compiler performs integral promotions on the operands, and then the right operand is converted to type int. The result has the same type as the left operand (after the arithmetic conversions)

The right operand should not have a negative value or a value that is greater than or equal to the width in bits of the expression being shifted. The result of bitwise shifts on such values is unpredictable

If the right operand has the value 0, the result is the value of the left operand (after the usual arithmetic conversions)

The << operator fills vacated bits with zeros. For example, if left_op has the value 4019, the bit pattern (in 16-bit format) of left_op is.

0000111110110011

Computers store all kinds of information as a stream of binary digits called bits. Whether you’re working with text, images, or videos, they all boil down to ones and zeros. Python’s bitwise operators let you manipulate those individual bits of data at the most granular level

You can use bitwise operators to implement algorithms such as compression, encryption, and error detection as well as to control physical devices in your Raspberry Pi project or elsewhere. Often, Python isolates you from the underlying bits with high-level abstractions. You’re more likely to find the overloaded flavors of bitwise operators in practice. But when you work with them in their original form, you’ll be surprised by their quirks

In this tutorial, you’ll learn how to

  • Use Python bitwise operators to manipulate individual bits
  • Read and write binary data in a platform-agnostic way
  • Use bitmasks to pack information on a single byte
  • Overload Python bitwise operators in custom data types
  • Hide secret messages in digital images

To get the complete source code of the digital watermarking example, and to extract a secret treat hidden in an image, click the link below

Dapatkan Kode Sumber. Click here to get the source code you’ll use to learn about Python’s bitwise operators in this tutorial

Overview of Python’s Bitwise Operators

Python comes with a few different kinds of operators, such as the arithmetic, logical, and comparison operators. You can think of them as functions that take advantage of a more compact prefix and infix syntax

Note. Python does not include postfix operators like the increment (

>>> (age >= 18) & ~is_self_excluded
0
9) or decrement (
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
0) operators available in C

Bitwise operators look virtually the same across different programming languages

OperatorExampleMeaning

>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
1
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
2Bitwise AND
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
3
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
4Bitwise OR
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
5
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
6Bitwise XOR (exclusive OR)
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
7
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
8Bitwise NOT
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
9
>>> (42).bit_length()
6
00Bitwise left shift
>>> (42).bit_length()
6
01
>>> (42).bit_length()
6
02Bitwise right shift

As you can see, they’re denoted with strange-looking symbols instead of words. This makes them stand out in Python as slightly less verbose than you might be used to seeing. You probably wouldn’t be able to figure out their meaning just by looking at them

Note. If you’re coming from another programming language such as Java, then you’ll immediately notice that Python is missing the unsigned right shift operator denoted by three greater-than signs (

>>> (42).bit_length()
6
03)

This has to do with how Python internally. Since integers in Python can have an infinite number of bits, the sign bit doesn’t have a fixed position. In fact, there’s no sign bit at all in Python

Most of the bitwise operators are binary, which means that they expect two operands to work with, typically referred to as the left operand and the right operand. Bitwise NOT (

>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
7) is the only unary bitwise operator since it expects just one operand

All binary bitwise operators have a corresponding compound operator that performs an augmented assignment

OperatorExampleEquivalent to

>>> (42).bit_length()
6
05
>>> (42).bit_length()
6
06
>>> (42).bit_length()
6
07
>>> (42).bit_length()
6
08
>>> (42).bit_length()
6
09
>>> (42).bit_length()
6
10
>>> (42).bit_length()
6
11
>>> (42).bit_length()
6
12
>>> (42).bit_length()
6
13
>>> (42).bit_length()
6
14
>>> (42).bit_length()
6
15
>>> (42).bit_length()
6
16
>>> (42).bit_length()
6
17
>>> (42).bit_length()
6
18
>>> (42).bit_length()
6
19

These are shorthand notations for updating the left operand in place

That’s all there is to Python’s bitwise operator syntax. Now you’re ready to take a closer look at each of the operators to understand where they’re most useful and how you can use them. First, you’ll get a quick refresher on the binary system before looking at two categories of bitwise operators. the bitwise logical operators and the bitwise shift operators

Remove ads

Binary System in Five Minutes

Before moving on, take a moment to brush up your knowledge of the binary system, which is essential to understanding bitwise operators. If you’re already comfortable with it, then go ahead and jump to the section below

Why Use Binary?

There are an infinite number of ways to represent numbers. Since ancient times, people have developed different notations, such as Roman numerals and Egyptian hieroglyphs. Most modern civilizations use positional notation, which is efficient, flexible, and well suited for doing arithmetic

A notable feature of any positional system is its base, which represents the number of digits available. People naturally favor the base-ten numeral system, also known as the decimal system, because it plays nicely with counting on fingers

Computers, on the other hand, treat data as a bunch of numbers expressed in the base-two numeral system, more commonly known as the binary system. Such numbers are composed of only two digits, zero and one

Note. In math books, the base of a numeric literal is commonly denoted with a subscript that appears slightly below the baseline, such as 4210

For example, the binary number 100111002 is equivalent to 15610 in the base-ten system. Because there are ten numerals in the decimal system—zero through nine—it usually takes fewer digits to write the same number in base ten than in base two

Note. You can’t tell a numeral system just by looking at a given number’s digits

For example, the decimal number 10110 happens to use only binary digits. But it represents a completely different value than its binary counterpart, 1012, which is equivalent to 510

The binary system requires more storage space than the decimal system but is much less complicated to implement in hardware. While you need more building blocks, they’re easier to make, and there are fewer types of them. That’s like breaking down your code into more modular and reusable pieces

More importantly, however, the binary system is perfect for electronic devices, which translate digits into different voltage levels. Because voltage likes to drift up and down due to various kinds of noise, you want to keep sufficient distance between consecutive voltages. Otherwise, the signal might end up distorted

By employing only two states, you make the system more reliable and resistant to noise. Alternatively, you could jack up the voltage, but that would also increase the power consumption, which you definitely want to avoid

How Does Binary Work?

Imagine for a moment that you had only two fingers to count on. You could count a zero, a one, and a two. But when you ran out of fingers, you’d need to note how many times you had already counted to two and then start over until you reached two again

DecimalFingersEightsFoursTwosOnesBinary010✊000002110☝️000112210✌️0010102310✌️+☝️0011112410✌️✌️01001002510✌️✌️+☝️01011012610✌️✌️+✌️01101102710✌️✌️+✌️+☝️01111112810✌️✌️✌️✌️100010002910✌️✌️✌️✌️+☝️1001100121010✌️✌️✌️✌️+✌️1010101021110

Every time you wrote down another pair of fingers, you’d also need to group them by powers of two, which is the base of the system. For example, to count up to thirteen, you would have to use both of your fingers six times and then use one more finger. Jari-jari Anda bisa disusun menjadi satu delapan, satu empat, dan satu satu

These powers of two correspond to digit positions in a binary number and tell you exactly which bits to switch on. They grow right to left, starting at the least-significant bit, which determines if the number is even or odd

Positional notation is like the odometer in your car. Once a digit in a particular position reaches its maximum value, which is one in the binary system, it rolls over to zero and the one carries over to the left. This can have a cascading effect if there are already some ones to the left of the digit

How Computers Use Binary

Now that you know the basic principles of the binary system and why computers use it, you’re ready to learn how they represent data with it

Before any piece of information can be reproduced in digital form, you have to break it down into numbers and then convert them to the binary system. Misalnya, teks biasa dapat dianggap sebagai rangkaian karakter. Anda dapat menetapkan nomor arbitrer untuk setiap karakter atau memilih pengkodean karakter yang ada seperti ASCII, ISO-8859-1, atau UTF-8

Dalam Python, string direpresentasikan sebagai array poin kode Unicode. Untuk mengungkapkan nilai ordinalnya, panggil

>>> (42).bit_length()
6
20 pada setiap karakter

>>>

>>> [ord(character) for character in "€uro"]
[8364, 117, 114, 111]
_

Angka yang dihasilkan secara unik mengidentifikasi karakter teks dalam ruang Unicode, tetapi ditampilkan dalam bentuk desimal. Anda ingin menulis ulang menggunakan digit biner

KarakterTitik Kode DesimalTitik Kode Biner€836410100000101011002u1171011101012r1141011100102o1111011011112

Perhatikan bahwa panjang bit, yang merupakan jumlah digit biner, sangat bervariasi antar karakter. Tanda euro (

>>> (42).bit_length()
6
21) membutuhkan empat belas bit, sedangkan karakter lainnya dapat dengan nyaman ditampung pada tujuh bit

Catatan. Inilah cara Anda dapat memeriksa panjang bit bilangan bulat apa pun dengan Python

>>>

>>> (42).bit_length()
6
_

Tanpa sepasang tanda kurung di sekitar angka, itu akan diperlakukan sebagai literal titik-mengambang dengan titik desimal

Panjang bit variabel bermasalah. Jika Anda meletakkan angka-angka biner itu di samping satu sama lain pada cakram optik, misalnya, maka Anda akan mendapatkan aliran bit yang panjang tanpa batas yang jelas antara karakter.

100000101011001110101111001011011112

Salah satu cara untuk mengetahui bagaimana menginterpretasikan informasi ini adalah dengan menetapkan pola bit dengan panjang tetap untuk semua karakter. Dalam komputasi modern, unit informasi terkecil, yang disebut oktet atau byte, terdiri dari delapan bit yang dapat menyimpan 256 nilai berbeda.

Anda dapat mengisi poin kode biner Anda dengan angka nol di depan untuk menyatakannya dalam satuan byte

KarakterTitik Kode DesimalTitik Kode Biner€83641000100000 101011002u1171000000000 011101012r1141000000000 011100102o1111000000000 011011112

Sekarang setiap karakter membutuhkan dua byte, atau 16 bit. Secara total, ukuran teks asli Anda hampir dua kali lipat, tetapi setidaknya dikodekan dengan andal

You can use Huffman coding to find unambiguous bit patterns for every character in a particular text or use a more suitable character encoding. For example, to save space, UTF-8 intentionally favors Latin letters over symbols that you’re less likely to find in an English text

>>>

>>> len("€uro".encode("utf-8"))
6

Encoded according to the UTF-8 standard, the entire text takes six bytes. Since UTF-8 is a superset of ASCII, the letters

>>> (42).bit_length()
6
22,
>>> (42).bit_length()
6
23, and
>>> (42).bit_length()
6
24 occupy one byte each, whereas the euro symbol takes three bytes in this encoding

>>>

>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1

Jenis informasi lain dapat didigitalkan mirip dengan teks. Raster images are made of pixels, with every pixel having channels that represent color intensities as numbers. Sound waveforms contain numbers corresponding to air pressure at a given sampling interval. Three-dimensional models are built from geometric shapes defined by their vertices, and so forth

At the end of the day, everything is a number

Remove ads

Bitwise Logical Operators

You can use bitwise operators to perform on individual bits. That’s analogous to using logical operators such as

>>> (42).bit_length()
6
25,
>>> (42).bit_length()
6
26, and
>>> (42).bit_length()
6
27, but on a bit level. The similarities between bitwise and logical operators go beyond that

It’s possible to evaluate Boolean expressions with bitwise operators instead of logical operators, but such overuse is generally discouraged. If you’re interested in the details, then you can expand the box below to find out more

Evaluating Boolean Expressions With Bitwise OperatorsShow/Hide

The ordinary way of specifying compound Boolean expressions in Python is to use the logical operators that connect adjacent predicates, like this

if age >= 18 and not is_self_excluded:
    print("You can gamble")

Here, you check if the user is at least eighteen years old and if they haven’t opted out of gambling. You can rewrite that condition using bitwise operators

if age >= 18 & ~is_self_excluded:
    print("You can gamble")

Although this expression is syntactically correct, there are a few problems with it. First, it’s arguably less readable. Second, it doesn’t work as expected for all groups of data. You can demonstrate that by choosing specific operand values

>>>

>>> age = 18
>>> is_self_excluded = True
>>> age >= 18 & ~is_self_excluded  # Bitwise logical operators
True
>>> age >= 18 and not is_self_excluded  # Logical operators
False

The expression made of the bitwise operators evaluates to

>>> (42).bit_length()
6
28, while the same expression built from the logical operators evaluates to
>>> (42).bit_length()
6
29. That’s because bitwise operators take over the comparison operators, changing how the whole expression is interpreted

>>>

>>> age >= (18 & ~is_self_excluded)
True

It’s as if someone put implicit parentheses around the wrong operands. Untuk memperbaikinya, Anda dapat menempatkan tanda kurung eksplisit, yang akan menerapkan urutan evaluasi yang benar

>>>

>>> (age >= 18) & ~is_self_excluded
0

However, you no longer get a Boolean result. Python bitwise operators were designed primarily to work with integers, so their operands automatically get casted if needed. This may not always be possible, though

While you can use truthy and falsy integers in a Boolean context, it’s a known antipattern that can cost you long hours of unnecessary debugging. You’re better off following the Zen of Python to save yourself the trouble

Last but not least, you may deliberately want to use bitwise operators to disable the short-circuit evaluation of Boolean expressions. Expressions using logical operators are evaluated lazily from left to right. In other words, the evaluation stops as soon as the result of the entire expression is known

>>>

>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True

In the second example, the right operand isn’t called at all because the value of the entire expression has already been determined by the value of the left operand. No matter what the right operand is, it won’t affect the result, so there’s no point in calling it unless you rely on side effects

There are idioms, such as falling back to a default value, that take advantage of this peculiarity

>>>

>>> (42).bit_length()
6
0

A Boolean expression takes the value of the last evaluated operand. The operand becomes truthy or falsy inside the expression but retains its original type and value afterward. In particular, a positive integer on the left gets propagated, while a zero gets discarded

Unlike their logical counterparts, bitwise operators are evaluated eagerly

>>>

>>> (42).bit_length()
6
1

Even though knowing the left operand is sufficient to determine the value of the entire expression, all operands are always evaluated unconditionally

Unless you have a strong reason and know what you’re doing, you should use bitwise operators only for controlling bits. It’s too easy to get it wrong otherwise. In most cases, you’ll want to pass integers as arguments to the bitwise operators

Sedikit demi sedikit DAN

The bitwise AND operator (

>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
1) performs logical conjunction on the corresponding bits of its operands. For each pair of bits occupying the same position in the two numbers, it returns a one only when both bits are switched on

Apa itu shift kiri dan shift kanan di python?

The resulting bit pattern is an intersection of the operator’s arguments. It has two bits turned on in the positions where both operands are ones. In all other places, at least one of the inputs has a zero bit

Arithmetically, this is equivalent to a product of two bit values. You can calculate the bitwise AND of numbers a and b by multiplying their bits at every index i

Apa itu shift kiri dan shift kanan di python?

Here’s a concrete example

ExpressionBinary ValueDecimal Value

>>> (42).bit_length()
6
3110011100215610
>>> (42).bit_length()
6
3211010025210
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
21010022010

A one multiplied by one gives one, but anything multiplied by zero will always result in zero. Alternatively, you can take the of the two bits in each pair. Notice that when operands have unequal bit-lengths, the shorter one is automatically padded with zeros to the left

Sedikit demi sedikit ATAU

Bitwise OR operator (

>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
3) melakukan disjungsi logis. Untuk setiap pasangan bit yang sesuai, ia mengembalikan satu jika setidaknya salah satunya diaktifkan

Apa itu shift kiri dan shift kanan di python?

Pola bit yang dihasilkan adalah gabungan dari argumen operator. Ini memiliki lima bit yang dihidupkan di mana salah satu operan memiliki satu. Hanya kombinasi dari dua angka nol yang menghasilkan angka nol pada hasil akhir

Aritmatika di belakangnya adalah kombinasi dari jumlah dan produk dari nilai bit. Untuk menghitung bitwise OR dari angka a dan b, Anda perlu menerapkan rumus berikut ke bitnya di setiap indeks i

Apa itu shift kiri dan shift kanan di python?

Ini contoh nyata

ExpressionBinary ValueDecimal Value

>>> (42).bit_length()
6
3110011100215610
>>> (42).bit_length()
6
3211010025210
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
410111100218810

Ini hampir seperti jumlah dari dua bit tetapi dijepit di ujung yang lebih tinggi sehingga tidak pernah melebihi nilai satu. Anda juga bisa mengambil dari dua bit di setiap pasangan untuk mendapatkan hasil yang sama

Remove ads

XOR bitwise

Tidak seperti bitwise , , dan , operator XOR bitwise (

>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
5) tidak memiliki pasangan logis di Python. Namun, Anda dapat mensimulasikannya dengan membangun di atas operator yang ada

>>> (42).bit_length()
6
2

Ini mengevaluasi dua kondisi yang saling eksklusif dan memberi tahu Anda apakah salah satunya terpenuhi. Misalnya, seseorang bisa menjadi anak di bawah umur atau orang dewasa, tetapi tidak keduanya sekaligus. Sebaliknya, seseorang tidak mungkin menjadi anak di bawah umur atau orang dewasa. Pilihan itu wajib

Nama XOR berarti "eksklusif atau" karena melakukan disjungsi eksklusif pada pasangan bit. Dengan kata lain, setiap pasangan bit harus mengandung nilai bit yang berlawanan untuk menghasilkan satu

Apa itu shift kiri dan shift kanan di python?

Secara visual, ini adalah perbedaan simetris dari argumen operator. Ada tiga bit yang diaktifkan pada hasil di mana kedua angka tersebut memiliki nilai bit yang berbeda. Bit di posisi yang tersisa dibatalkan karena sama

Mirip dengan operator OR bitwise, aritmatika XOR melibatkan penjumlahan. Namun, sementara bitwise OR menjepit nilai pada satu, operator XOR membungkusnya dengan jumlah modulo dua

Apa itu shift kiri dan shift kanan di python?

Modulo adalah fungsi dari dua bilangan—pembagi dan pembagi—yang melakukan pembagian dan mengembalikan sisanya. Di Python, ada operator modulo bawaan yang dilambangkan dengan tanda persen (

>>> (42).bit_length()
6
39)

Sekali lagi, Anda dapat mengonfirmasi rumus dengan melihat contoh

ExpressionBinary ValueDecimal Value

>>> (42).bit_length()
6
3110011100215610
>>> (42).bit_length()
6
3211010025210
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
610101000216810

Hasil penjumlahan dua nol atau dua satu menghasilkan bilangan bulat bila dibagi dua, sehingga hasilnya memiliki sisa nol. Namun, ketika Anda membagi jumlah dari dua nilai bit yang berbeda dengan dua, Anda mendapatkan pecahan dengan sisa satu. Rumus yang lebih mudah untuk operator XOR adalah perbedaan antara maksimum dan minimum dari kedua bit di setiap pasangan

Bitwise TIDAK

Yang terakhir dari operator logis bitwise adalah operator NOT bitwise (

>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
7), yang mengharapkan hanya satu argumen, menjadikannya satu-satunya operator bitwise unary. Itu melakukan negasi logis pada nomor tertentu dengan membalik semua bitnya

Apa itu shift kiri dan shift kanan di python?

Bit terbalik adalah pelengkap satu, yang mengubah nol menjadi satu dan satu menjadi nol. Itu dapat dinyatakan secara aritmatika sebagai pengurangan nilai bit individu dari satu

Apa itu shift kiri dan shift kanan di python?

Berikut adalah contoh yang menunjukkan salah satu nomor yang digunakan sebelumnya

ExpressionBinary ValueDecimal Value

>>> (42).bit_length()
6
3110011100215610
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
8110001129910

Meskipun operator NOT bitwise tampaknya yang paling mudah dari semuanya, Anda harus sangat berhati-hati saat menggunakannya dengan Python. Semua yang telah Anda baca sejauh ini didasarkan pada asumsi bahwa angka direpresentasikan dengan bilangan bulat tak bertanda

Catatan. Tipe data yang tidak ditandatangani tidak memungkinkan Anda menyimpan angka negatif seperti -273 karena tidak ada ruang untuk masuk dalam pola bit reguler. Mencoba melakukannya akan menghasilkan kesalahan kompilasi, pengecualian runtime, atau integer overflow tergantung pada bahasa yang digunakan

Meskipun ada cara untuk mensimulasikan, Python tidak mendukungnya secara native. Itu berarti semua angka memiliki tanda implisit yang melekat padanya apakah Anda menentukannya atau tidak. Ini menunjukkan ketika Anda melakukan bitwise BUKAN dari angka apa pun

>>>

>>> (42).bit_length()
6
3

Instead of the expected 9910, you get a negative value. Alasan untuk ini akan menjadi jelas setelah Anda mempelajari berbagai macamnya. Untuk saat ini, solusi perbaikan cepat adalah memanfaatkan operator AND bitwise

>>>

>>> (42).bit_length()
6
4

Itu adalah contoh sempurna dari , yang akan Anda jelajahi di salah satu bagian yang akan datang

Remove ads

Operator Pergeseran Bitwise

Operator pergeseran bitwise adalah jenis alat lain untuk manipulasi bit. They let you move the bits around, which will be handy for creating bitmasks later on. In the past, they were often used to improve the speed of certain mathematical operations

Left Shift

Operator bitwise shift kiri (

>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
_9) memindahkan bit operan pertamanya ke kiri dengan jumlah tempat yang ditentukan dalam operan keduanya. It also takes care of inserting enough zero bits to fill the gap that arises on the right edge of the new bit pattern

Apa itu shift kiri dan shift kanan di python?

Menggeser satu bit ke kiri satu tempat akan menggandakan nilainya. Misalnya, alih-alih dua, bit akan menunjukkan empat setelah pergeseran. Memindahkannya dua tempat ke kiri akan melipatgandakan nilai yang dihasilkan. When you add up all the bits in a given number, you’ll notice that it also gets doubled with every place shifted

ExpressionBinary ValueDecimal Value

>>> (42).bit_length()
6
3110011123910
>>> (42).bit_length()
6
48100111027810
>>> (42).bit_length()
6
4910011100215610
>>> (42).bit_length()
6
50100111000231210

Secara umum, menggeser bit ke kiri sama dengan mengalikan angka dengan pangkat dua, dengan eksponen sama dengan jumlah tempat yang digeser

Apa itu shift kiri dan shift kanan di python?

Pergeseran ke kiri dulunya merupakan teknik pengoptimalan yang populer karena pergeseran bit adalah instruksi tunggal dan lebih murah untuk dihitung daripada eksponen atau perkalian. Namun hari ini, kompiler dan juru bahasa, termasuk Python, cukup mampu mengoptimalkan kode Anda di belakang layar

Catatan. Jangan gunakan operator bit shift sebagai sarana pengoptimalan prematur dengan Python. You won’t see a difference in execution speed, but you’ll most definitely make your code less readable

On paper, the bit pattern resulting from a left shift becomes longer by as many places as you shift it. That’s also true for Python in general because of how it handles integers. Namun, dalam sebagian besar kasus praktis, Anda ingin membatasi panjang pola bit menjadi kelipatan delapan, yang merupakan panjang byte standar

For example, if you’re working with a single byte, then shifting it to the left should discard all the bits that go beyond its left boundary

Apa itu shift kiri dan shift kanan di python?

Ini seperti melihat aliran bit yang tidak terbatas melalui jendela dengan panjang tetap. Ada beberapa trik yang memungkinkan Anda melakukan ini dengan Python. Misalnya, Anda dapat menerapkan a dengan operator AND bitwise

>>>

>>> (42).bit_length()
6
5

Menggeser 3910 sebanyak tiga tempat ke kiri mengembalikan angka yang lebih tinggi dari nilai maksimum yang dapat Anda simpan pada satu byte. Dibutuhkan sembilan bit, sedangkan satu byte hanya memiliki delapan. Untuk memotong satu bit ekstra di sebelah kiri, Anda dapat menerapkan bitmask dengan nilai yang sesuai. If you’d like to keep more or fewer bits, then you’ll need to modify the mask value accordingly

Pergeseran Kanan

Operator bitwise shift kanan (

>>> (42).bit_length()
6
_01) analog dengan yang kiri, tetapi alih-alih memindahkan bit ke kiri, ia mendorongnya ke kanan dengan jumlah tempat yang ditentukan. Bit paling kanan selalu dijatuhkan

Apa itu shift kiri dan shift kanan di python?

Every time you shift a bit to the right by one position, you halve its underlying value. Moving the same bit by two places to the right produces a quarter of the original value, and so on. Saat Anda menjumlahkan semua bit individual, Anda akan melihat bahwa aturan yang sama berlaku untuk angka yang diwakilinya

ExpressionBinary ValueDecimal Value

>>> (42).bit_length()
6
3110011101215710
>>> (42).bit_length()
6
53100111027810
>>> (42).bit_length()
6
5410011123910
>>> (42).bit_length()
6
551001121910

Membagi dua angka ganjil seperti 15710 akan menghasilkan pecahan. Untuk menghilangkannya, operator shift kanan otomatis hasilnya. Ini hampir sama dengan pembagian lantai dengan pangkat dua

Apa itu shift kiri dan shift kanan di python?

Sekali lagi, eksponen sesuai dengan jumlah tempat yang digeser ke kanan. In Python, you can leverage a dedicated operator to perform a floor division

>>>

>>> (42).bit_length()
6
6

Operator bitwise shift kanan dan operator pembagian lantai keduanya bekerja dengan cara yang sama, bahkan untuk bilangan negatif. Namun, pembagian lantai memungkinkan Anda memilih pembagi apa pun dan bukan hanya pangkat dua. Menggunakan pergeseran kanan bitwise adalah cara umum untuk meningkatkan kinerja beberapa divisi aritmatika

Note. Anda mungkin bertanya-tanya apa yang terjadi jika Anda kehabisan bit untuk digeser. Misalnya, ketika Anda mencoba mendorong lebih banyak tempat daripada jumlah bit

>>> ________12______7

Setelah tidak ada lagi bit yang diaktifkan, Anda terjebak dengan nilai nol. Zero divided by anything will always return zero. However, things get trickier when you right shift a negative number because the implicit sign bit gets in the way

>>> ________12______8

The rule of thumb is that, regardless of the sign, the result will be the same as a floor division by some power of two. Dasar pecahan negatif kecil selalu minus satu, dan itulah yang akan Anda dapatkan. Read on for a more detailed explanation

Sama seperti operator shift kiri, pola bit berubah ukurannya setelah shift kanan. While moving bits to the right makes the binary sequence shorter, it usually won’t matter because you can put as many zeros in front of a bit sequence as you like without changing the value. Misalnya, 1012 sama dengan 01012, demikian juga 000001012, asalkan Anda berurusan dengan bilangan nonnegatif

Sometimes you’ll want to keep a given bit-length after doing a right shift to align it against another value or to fit in somewhere. You can do that by applying a bitmask

Apa itu shift kiri dan shift kanan di python?

Itu hanya mengukir bit yang Anda minati dan mengisi pola bit dengan nol di depan jika perlu

Penanganan bilangan negatif dalam Python sedikit berbeda dari pendekatan tradisional untuk pengalihan bitwise. In the next section, you’ll examine this in more detail

Remove ads

Pergeseran Aritmatika vs Logis

You can further categorize the bitwise shift operators as arithmetic and logical shift operators. While Python only lets you do the arithmetic shift, it’s worthwhile to know how other programming languages implement the bitwise shift operators to avoid confusion and surprises

Perbedaan ini berasal dari cara mereka menangani bit tanda, yang biasanya terletak di tepi paling kiri dari urutan biner bertanda. In practice, it’s relevant only to the right shift operator, which can cause a number to flip its sign, leading to integer overflow

Note. Java dan JavaScript, misalnya, membedakan operator pergeseran kanan logis dengan tambahan tanda lebih besar dari (

>>> (42).bit_length()
6
03). Since the left shift operator behaves consistently across both kinds of shifts, these languages don’t define a logical left shift counterpart

Secara konvensional, bit tanda yang dihidupkan menunjukkan angka negatif, yang membantu menjaga sifat aritmatika dari deret biner

Decimal ValueSigned Binary ValueSign BitSignMeaning-100101001110021-Negative number28100001110020+Positive number or zero

Melihat dari kiri pada dua urutan biner ini, Anda dapat melihat bahwa bit pertama mereka membawa informasi tanda, sedangkan bagian sisanya terdiri dari bit magnitudo, yang sama untuk kedua angka.

Note. The specific decimal values will depend on how you decide to express signed numbers in binary. It varies between languages and gets even more complicated in Python, so you can ignore it for the moment. Anda akan memiliki gambaran yang lebih baik setelah Anda masuk ke bagian di bawah ini

Pergeseran kanan logis, juga dikenal sebagai pergeseran kanan tanpa tanda atau pergeseran kanan pengisian-nol, memindahkan seluruh urutan biner, termasuk bit tanda, dan mengisi celah yang dihasilkan di sebelah kiri dengan nol

Apa itu shift kiri dan shift kanan di python?

Notice how the information about the sign of the number is lost. Regardless of the original sign, it’ll always produce a nonnegative integer because the sign bit gets replaced by zero. As long as you aren’t interested in the numeric values, a logical right shift can be useful in processing low-level binary data

Namun, karena bilangan biner bertanda biasanya disimpan pada urutan bit dengan panjang tetap di sebagian besar bahasa, ini dapat membuat hasilnya membungkus nilai ekstrem. Anda dapat melihat ini di alat Java Shell yang interaktif

>>> (42).bit_length()
6
_9

Angka yang dihasilkan mengubah tandanya dari negatif menjadi positif, tetapi juga meluap, berakhir sangat dekat dengan bilangan bulat maksimum Java

>>> len("€uro".encode("utf-8"))
6
0

This number may seem arbitrary at first glance, but it’s directly related to the number of bits that Java allocates for the

>>> (42).bit_length()
6
57 data type

>>> len("€uro".encode("utf-8"))
6
1

Ini menggunakan 32 bit untuk menyimpan dalam representasi komplemen dua. Saat Anda mengeluarkan bit tanda, tersisa 31 bit, yang nilai desimal maksimumnya sama dengan 231 - 1, atau 214748364710

Python, di sisi lain, menyimpan bilangan bulat seolah-olah ada jumlah bit tak terbatas yang Anda inginkan. Konsekuensinya, operator shift kanan yang logis tidak akan terdefinisi dengan baik dalam Python murni, sehingga hilang dari bahasa. Anda masih bisa mensimulasikannya

Salah satu cara melakukannya adalah dengan memanfaatkan tipe data unsigned yang tersedia di C yang diekspos melalui modul

>>> (42).bit_length()
6
58 bawaan

>>>

>>> len("€uro".encode("utf-8"))
6
2

Mereka membiarkan Anda memasukkan angka negatif tetapi tidak melampirkan arti khusus apa pun pada bit tanda. Itu diperlakukan seperti bit besaran lainnya

Meskipun hanya ada beberapa tipe integer unsigned yang telah ditentukan sebelumnya di C, yang berbeda dalam panjang bit, Anda dapat membuat fungsi khusus di Python untuk menangani panjang bit yang sewenang-wenang

>>>

>>> len("€uro".encode("utf-8"))
6
3

Ini mengubah urutan bit yang ditandatangani menjadi yang tidak ditandatangani dan kemudian melakukan pergeseran kanan aritmatika biasa

Namun, karena urutan bit dalam Python tidak memiliki panjang yang tetap, mereka tidak benar-benar memiliki bit tanda. Selain itu, mereka tidak menggunakan representasi komplemen dua tradisional seperti di C atau Java. Untuk menguranginya, Anda dapat memanfaatkan operasi modulo, yang akan mempertahankan pola bit asli untuk bilangan bulat positif sambil membungkus bilangan negatif dengan tepat.

Pergeseran kanan aritmatika (

>>> (42).bit_length()
6
01), terkadang disebut operator pergeseran kanan bertanda, mempertahankan tanda angka dengan mereplikasi bit tandanya sebelum memindahkan bit ke kanan

Apa itu shift kiri dan shift kanan di python?

Dengan kata lain, ini mengisi celah di sebelah kiri dengan bit tanda apa pun. Dikombinasikan dengan representasi pelengkap dua biner bertanda, ini menghasilkan nilai yang benar secara aritmatika. Terlepas dari apakah angkanya positif atau negatif, pergeseran ke kanan aritmatika setara dengan pembagian lantai

Seperti yang akan Anda ketahui, Python tidak selalu menyimpan bilangan bulat dalam biner komplemen dua biasa. Alih-alih, ini mengikuti strategi adaptif khusus yang berfungsi seperti dengan jumlah bit yang tidak terbatas. Itu mengubah angka bolak-balik antara representasi internal mereka dan komplemen dua untuk meniru perilaku standar dari pergeseran aritmatika

Remove ads

Representasi Bilangan Biner

Anda telah mengalami secara langsung kurangnya tipe data unsigned di Python saat menggunakan negasi bitwise (

>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
7) dan operator shift kanan (
>>> (42).bit_length()
6
01). Anda telah melihat petunjuk tentang pendekatan penyimpanan yang tidak biasa, yang membuat penanganan angka negatif menjadi rumit. Untuk menggunakan operator bitwise secara efektif, Anda perlu mengetahui tentang berbagai representasi angka dalam biner

Bilangan bulat yang tidak ditandatangani

Dalam bahasa pemrograman seperti C, Anda memilih apakah akan menggunakan ragam bertanda atau tidak bertanda dari tipe numerik tertentu. Tipe data yang tidak ditandatangani lebih cocok jika Anda tahu pasti bahwa Anda tidak perlu berurusan dengan angka negatif. Dengan mengalokasikan satu bit ekstra itu, yang jika tidak berfungsi sebagai bit tanda, Anda secara praktis menggandakan rentang nilai yang tersedia

Itu juga membuat segalanya sedikit lebih aman dengan meningkatkan batas maksimum sebelum luapan terjadi. Namun, luapan hanya terjadi dengan panjang bit tetap, sehingga tidak relevan dengan Python, yang tidak memiliki batasan seperti itu

Cara tercepat untuk merasakan tipe numerik unsigned di Python adalah dengan menggunakan modul

>>> (42).bit_length()
6
58 yang disebutkan sebelumnya

>>>

>>> len("€uro".encode("utf-8"))
6
4

Karena tidak ada bit tanda dalam bilangan bulat seperti itu, semua bitnya mewakili besarnya angka. Melewati angka negatif memaksa Python untuk menginterpretasikan kembali pola bit seolah-olah hanya memiliki bit besaran

Integer yang ditandatangani

Tanda angka hanya memiliki dua status. Jika Anda mengabaikan nol sesaat, maka itu bisa menjadi positif atau negatif, yang diterjemahkan dengan baik ke sistem biner. Namun ada beberapa cara alternatif untuk merepresentasikan bilangan bulat bertanda dalam biner, masing-masing dengan kelebihan dan kekurangannya sendiri

Mungkin yang paling mudah adalah tanda-magnitudo, yang dibangun secara alami di atas bilangan bulat tak bertanda. Ketika urutan biner ditafsirkan sebagai besaran tanda, bit tersebut memainkan peran sebagai bit tanda, sedangkan bit lainnya bekerja sama seperti biasanya.

Urutan BinerTanda-Magnitudo NilaiUnsigned Value00101010242104210101010102-421017010

Nol pada bit paling kiri menunjukkan angka positif (

>>> (42).bit_length()
6
63), dan satu menunjukkan angka negatif (
>>> (42).bit_length()
6
64). Perhatikan bahwa bit tanda tidak berkontribusi pada nilai absolut angka dalam representasi magnitudo tanda. Itu ada hanya untuk membiarkan Anda membalik tanda bit yang tersisa

Mengapa sedikit paling kiri?

Itu membuat pengindeksan bit utuh, yang, pada gilirannya, membantu menjaga kompatibilitas mundur dari bobot bit yang digunakan untuk menghitung nilai desimal dari urutan biner. Namun, tidak semua tentang magnitudo tanda begitu hebat

Catatan. Representasi biner dari bilangan bulat yang ditandatangani hanya masuk akal pada urutan bit dengan panjang tetap. Jika tidak, Anda tidak dapat mengetahui di mana bit tanda itu berada. Namun, dalam Python, Anda dapat merepresentasikan bilangan bulat dengan bit sebanyak yang Anda suka

>>>

>>> len("€uro".encode("utf-8"))
6
5

Apakah itu empat atau delapan bit tanda akan selalu ditemukan di posisi paling kiri

Rentang nilai yang dapat Anda simpan dalam pola bit tanda-magnitudo bersifat simetris. But it also means that you end up with two ways to convey zero

Urutan BinerNilai Magnitudo TandaNilai Tidak Bertanda000000002+010010100000002-01012810

Nol secara teknis tidak memiliki tanda, tetapi tidak ada cara untuk tidak menyertakannya dalam besaran tanda. Meskipun memiliki angka nol yang ambigu tidak ideal dalam banyak kasus, itu bukanlah bagian terburuk dari cerita. Kelemahan terbesar dari metode ini adalah aritmatika biner yang rumit

Saat Anda menerapkan aritmatika biner standar ke angka yang disimpan dalam magnitudo tanda, ini mungkin tidak memberi Anda hasil yang diharapkan. Misalnya, menjumlahkan dua bilangan yang sama besar tetapi berlawanan tanda tidak akan menghilangkannya

ExpressionBinary SequenceSign-Magnitude Value

>>> (42).bit_length()
6
310010101024210
>>> (42).bit_length()
6
32101010102-4210
>>> (42).bit_length()
6
67110101002-8410

Jumlah 42 dan -42 tidak menghasilkan nol. Juga, bit carryover kadang-kadang dapat merambat dari magnitudo ke bit tanda, membalikkan tanda dan menghasilkan hasil yang tidak diharapkan.

Untuk mengatasi masalah ini, beberapa komputer awal menggunakan representasi komplemen seseorang. Idenya adalah mengubah cara bilangan desimal dipetakan ke deret biner tertentu sehingga dapat dijumlahkan dengan benar. Untuk menyelami lebih dalam pelengkap seseorang, Anda dapat memperluas bagian di bawah ini

Pelengkap SeseorangTampilkan/Sembunyikan

Dalam komplemen satu, bilangan positif sama dengan besaran tanda, tetapi bilangan negatif diperoleh dengan membalik bit bilangan positif menggunakan bitwise NOT

Barisan Positif Barisan NegatifNilai Besaran000000002111111112±010000000012111111102±110000000102111111012±210⋮⋮⋮0111111112100000002±12710

Ini mempertahankan arti asli dari bit tanda, jadi bilangan positif masih dimulai dengan nol biner, sedangkan bilangan negatif dimulai dengan bilangan biner. Demikian pula, rentang nilai tetap simetris dan terus memiliki dua cara untuk merepresentasikan nol. Namun, urutan biner bilangan negatif dalam komplemen satu disusun dalam urutan terbalik dibandingkan dengan besaran tanda

One’s ComplementSign-MagnitudeDecimal Value111111112100000002-010111111102100000012-110111111012100000102-210↓↑⋮100000102111111012-12510100000012111111102-12610100000002111111112-12710

Berkat itu, Anda sekarang dapat menambahkan dua angka dengan lebih andal karena bit tanda tidak memerlukan perlakuan khusus. Jika carryover berasal dari bit tanda, itu diumpankan kembali di tepi kanan urutan biner alih-alih dibuang begitu saja. Ini memastikan hasil yang benar

Namun demikian, komputer modern tidak menggunakan komplemen satu untuk merepresentasikan bilangan bulat karena ada cara yang lebih baik yang disebut komplemen dua. Dengan menerapkan sedikit modifikasi, Anda dapat menghilangkan nol ganda dan menyederhanakan aritmatika biner sekaligus. Untuk menjelajahi dua komplemen lebih detail, Anda dapat memperluas bagian di bawah ini

Pelengkap DuaTampilkan/Sembunyikan

Saat menemukan urutan bit dari nilai negatif dalam komplemen dua, triknya adalah menambahkan satu ke hasil setelah meniadakan bit

Barisan Positif Pelengkap Satu (NOT) Pelengkap Dua (NOT+1)0000000021111111112000000002000000012111111102111111112000000102111111012111111102⋮⋮⋮0110101010100

Ini mendorong urutan bit angka negatif turun satu tempat, menghilangkan minus nol yang terkenal. Minus yang lebih berguna akan mengambil alih pola bitnya

Sebagai efek samping, rentang nilai yang tersedia dalam komplemen dua menjadi asimetris, dengan batas bawah pangkat dua dan batas atas ganjil. Misalnya, bilangan bulat bertanda 8-bit akan memungkinkan Anda menyimpan angka dari -12810 hingga 12710 dalam komplemen dua

Two Complementone's ComplementDeCimal Value100000002N/A-1281010000121000000022-127101000001021000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000

Cara lain untuk mengatakannya adalah bahwa bit paling signifikan membawa tanda dan bagian dari besaran angka

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3Bit 2Bit 1Bit 0-2726252423222120-1286432168421

Notice the minus sign next to the leftmost bit weight. Memperoleh nilai desimal dari urutan biner seperti itu hanyalah masalah menambahkan kolom yang sesuai. Misalnya, nilai 110101102 dalam representasi komplemen dua bit 8 sama dengan jumlah. -12810 + 6410 + 1610 + 410 + 210 = -4210

Dengan representasi komplemen keduanya, Anda tidak perlu lagi khawatir tentang bit bawaan kecuali jika Anda ingin menggunakannya sebagai mekanisme deteksi luapan, yang cukup rapi.

Ada beberapa varian representasi angka bertanda lainnya, tetapi tidak sepopuler itu

Remove ads

Bilangan Floating-Point

Standar IEEE 754 mendefinisikan representasi biner untuk bilangan real yang terdiri dari bit tanda, eksponen, dan mantissa. Tanpa membahas terlalu banyak detail teknis, Anda dapat menganggapnya sebagai notasi ilmiah untuk bilangan biner. The decimal point “floats” around to accommodate a varying number of significant figures, except it’s a binary point

Dua tipe data yang sesuai dengan standar itu didukung secara luas

  1. Presisi tunggal. 1 bit tanda, 8 bit eksponen, 23 bit mantissa
  2. Double precision. 1 bit tanda, 11 bit eksponen, 52 bit mantissa

Tipe data

>>> (42).bit_length()
6
68 Python setara dengan tipe presisi ganda. Perhatikan bahwa beberapa aplikasi memerlukan lebih banyak atau lebih sedikit bit. Misalnya, format gambar OpenEXR memanfaatkan setengah presisi untuk merepresentasikan piksel dengan rentang warna dinamis yang tinggi pada ukuran file yang wajar

Angka Pi (π) memiliki representasi biner berikut dalam presisi tunggal ketika dibulatkan menjadi lima tempat desimal

Tanda Eksponen Mantissa02100000002. 100100100001111110100002

The sign bit works just like with integers, so zero denotes a positive number. Namun, untuk eksponen dan mantissa, aturan yang berbeda dapat diterapkan tergantung pada beberapa kasus tepi

Pertama, Anda perlu mengonversinya dari biner ke bentuk desimal

  • Eksponen. 12810
  • Mantissa. 2-1 + 2-4 + … + 2-19 = 29926110/52428810 ≈ 0. 57079510

Eksponen disimpan sebagai bilangan bulat tak bertanda, tetapi untuk memperhitungkan nilai negatif, eksponen biasanya memiliki bias sama dengan 12710 dalam presisi tunggal. Anda perlu menguranginya untuk memulihkan eksponen yang sebenarnya

Bit Mantissa mewakili pecahan, sehingga sesuai dengan kekuatan negatif dua. Selain itu, Anda perlu menambahkan satu ke mantissa karena mengasumsikan bit awal implisit sebelum titik radix dalam kasus khusus ini

Menyatukan semuanya, Anda sampai pada rumus berikut untuk mengubah bilangan biner titik-mengambang menjadi angka desimal

Apa itu shift kiri dan shift kanan di python?

When you substitute the variables for the actual values in the example above, you’ll be able to decipher the bit pattern of a floating-point number stored in single precision

Apa itu shift kiri dan shift kanan di python?

There it is, granted that Pi has been rounded to five decimal places. Anda akan mempelajari caranya nanti

Bilangan Titik Tetap

Sementara angka floating-point cocok untuk tujuan teknik, angka tersebut gagal dalam perhitungan moneter karena presisi yang terbatas. Misalnya, beberapa angka dengan representasi terbatas dalam notasi desimal hanya memiliki representasi tak terbatas dalam biner. Itu sering menghasilkan kesalahan pembulatan, yang dapat terakumulasi dari waktu ke waktu

>>>

>>> len("€uro".encode("utf-8"))
6
6

Dalam kasus seperti itu, Anda lebih baik menggunakan modul Python, yang mengimplementasikan aritmatika titik tetap dan memungkinkan Anda menentukan di mana harus meletakkan titik desimal pada panjang bit tertentu. Misalnya, Anda dapat menentukan berapa digit yang ingin Anda pertahankan

>>>

>>> len("€uro".encode("utf-8"))
6
7

However, it includes all digits, not just the fractional ones

Catatan. Jika Anda bekerja dengan bilangan rasional, Anda mungkin tertarik untuk melihat modul ________12______70, yang merupakan bagian dari pustaka standar Python

Jika Anda tidak dapat atau tidak ingin menggunakan tipe data titik tetap, cara langsung untuk menyimpan nilai mata uang dengan andal adalah dengan menskalakan jumlah ke unit terkecil, seperti sen, dan menyatakannya dengan bilangan bulat

Remove ads

Bilangan bulat dengan Python

Di masa lalu pemrograman, memori komputer sangat mahal. Oleh karena itu, bahasa akan memberi Anda kontrol yang cukup terperinci atas berapa banyak byte yang dialokasikan untuk data Anda. Mari kita intip beberapa tipe bilangan bulat dari C sebagai contoh

TypeSizeMinimum ValueMaximum Value

>>> (42).bit_length()
6
711 byte-128127
>>> (42).bit_length()
6
722 bytes-32,76832,767
>>> (42).bit_length()
6
734 bytes-2,147,483,6482,147,483,647
>>> (42).bit_length()
6
748 bytes-9,223,372,036,854,775,8089,223,372,036,854,775,807

Nilai-nilai ini mungkin berbeda dari platform ke platform. Namun, jenis numerik yang melimpah memungkinkan Anda mengatur data dalam memori dengan kompak. Ingatlah bahwa ini bahkan tidak termasuk tipe yang tidak ditandatangani

Di ujung lain spektrum adalah bahasa seperti JavaScript, yang hanya memiliki satu tipe numerik untuk mengatur semuanya. While this is less confusing for beginning programmers, it comes at the price of increased memory consumption, reduced processing efficiency, and decreased precision

Ketika berbicara tentang operator bitwise, penting untuk memahami bagaimana Python menangani bilangan bulat. Lagi pula, Anda akan menggunakan operator ini terutama untuk bekerja dengan bilangan bulat. Ada beberapa representasi bilangan bulat yang sangat berbeda di Python yang bergantung pada nilainya

Bilangan Bulat Diinternir

Di CPython, bilangan bulat yang sangat kecil antara -510 dan 25610 berada dalam cache global untuk mendapatkan beberapa kinerja karena angka dalam rentang tersebut biasanya digunakan. Dalam praktiknya, setiap kali Anda merujuk ke salah satu dari nilai tersebut, yang merupakan lajang yang dibuat saat startup juru bahasa, Python akan selalu memberikan contoh yang sama

>>> ________36______8

Kedua variabel memiliki kesamaan karena mengacu pada objek yang sama persis di memori. Itu khas dari tipe referensi tetapi bukan nilai yang tidak dapat diubah seperti bilangan bulat. Namun, saat Anda melampaui rentang nilai cache tersebut, Python akan mulai membuat salinan yang berbeda selama penugasan variabel

>>>

>>> len("€uro".encode("utf-8"))
6
9

Meskipun memiliki nilai yang sama, variabel-variabel ini menunjuk ke objek yang terpisah sekarang. Tapi jangan biarkan itu membodohi Anda. Python sesekali akan masuk dan mengoptimalkan kode Anda di belakang layar. Misalnya, ini akan meng-cache nomor yang muncul di baris yang sama berkali-kali terlepas dari nilainya

>>>

>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
0

Variables

>>> (42).bit_length()
6
31 and
>>> (42).bit_length()
6
32 are independent objects because they reside at different memory locations, while the numbers used literally in
>>> (42).bit_length()
6
77 are, in fact, the same object

Catatan. Magang adalah detail implementasi dari juru bahasa CPython, yang mungkin berubah di versi mendatang, jadi jangan mengandalkannya di program Anda

Menariknya, ada mekanisme interning string serupa di Python, yang berlaku untuk teks pendek yang hanya terdiri dari huruf ASCII. Ini membantu mempercepat pencarian kamus dengan memungkinkan kuncinya dibandingkan dengan alamat memori, atau pointer C, bukan dengan karakter string individual

Bilangan Bulat Presisi Tetap

Bilangan bulat yang kemungkinan besar Anda temukan di Python akan memanfaatkan tipe data C

>>> (42).bit_length()
6
78. Mereka menggunakan representasi biner komplemen dua klasik pada jumlah bit yang tetap. Panjang bit yang tepat akan bergantung pada platform perangkat keras, sistem operasi, dan versi juru bahasa Python Anda

Komputer modern biasanya menggunakan arsitektur 64-bit, jadi ini akan diterjemahkan menjadi angka desimal antara -263 dan 263 - 1. Anda dapat memeriksa nilai maksimum bilangan bulat presisi tetap di Python dengan cara berikut

>>>

>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
1

It’s huge. Kira-kira 9 juta kali jumlah bintang di galaksi kita, jadi cukup untuk penggunaan sehari-hari. Sementara nilai maksimum yang dapat Anda peras dari tipe

>>> (42).bit_length()
6
79 di C bahkan lebih besar, di urutan 1019, bilangan bulat di Python tidak memiliki batas teoretis. Untuk memungkinkan ini, angka yang tidak sesuai dengan urutan bit dengan panjang tetap disimpan secara berbeda di memori

Remove ads

Bilangan Bulat Presisi Sewenang-wenang

Apakah Anda ingat lagu K-pop populer "Gangnam Style" yang menjadi hit di seluruh dunia pada tahun 2012? . Soon after that, so many people had watched the video that it made the view counter overflow. YouTube tidak punya pilihan selain memutakhirkan penghitung mereka dari bilangan bulat bertanda 32-bit menjadi bilangan bulat 64-bit

Itu mungkin memberi banyak ruang kepala untuk penghitung tampilan, tetapi ada jumlah yang lebih besar lagi yang tidak biasa dalam kehidupan nyata, terutama di dunia ilmiah. Meskipun demikian, Python dapat menanganinya dengan mudah

>>>

>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
2

Angka ini memiliki lima puluh dua angka desimal. Diperlukan setidaknya 170 bit untuk merepresentasikannya dalam biner dengan pendekatan tradisional

>>>

>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
3

Karena mereka jauh di atas batas yang ditawarkan oleh tipe C mana pun, bilangan astronomi semacam itu diubah menjadi sistem posisi magnitudo tanda, yang basisnya adalah 230. Ya, Anda membacanya dengan benar. Sedangkan Anda memiliki sepuluh jari, Python memiliki lebih dari satu miliar

Sekali lagi, ini dapat bervariasi tergantung pada platform yang Anda gunakan saat ini. Jika ragu, Anda dapat memeriksa ulang

>>>

>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
4

Ini akan memberi tahu Anda berapa banyak bit yang digunakan per digit dan berapa ukuran dalam byte dari struktur C yang mendasarinya. Untuk mendapatkan yang sama di Python 2, Anda akan merujuk ke

>>> (42).bit_length()
6
80 atribut sebagai gantinya

Sementara konversi antara bilangan bulat presisi tetap dan sewenang-wenang ini dilakukan dengan mulus di bawah tenda di Python 3, ada saat ketika hal-hal menjadi lebih eksplisit. Untuk informasi lebih lanjut, Anda dapat memperluas kotak di bawah ini

>>> (42).bit_length()
6
73 dan
>>> (42).bit_length()
6
74 dengan Python 2Tampilkan/Sembunyikan

Di masa lalu, Python secara eksplisit mendefinisikan dua tipe integer yang berbeda

  1. Plain integer
  2. Bilangan bulat panjang

Yang pertama dimodelkan setelah tipe C

>>> (42).bit_length()
6
78, yang biasanya menempati 32 atau 64 bit dan menawarkan rentang nilai yang terbatas

>>>

>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
5

For bigger numbers, you were supposed to use the second type that didn’t come with a limit. Python akan secara otomatis mempromosikan bilangan bulat biasa menjadi bilangan panjang jika diperlukan

>>>

>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
6

Fitur ini mencegah kesalahan integer overflow. Perhatikan huruf

>>> (42).bit_length()
6
_84 di akhir literal, yang dapat digunakan untuk memaksakan jenis yang diberikan dengan tangan

>>> ________40______7

Akhirnya, kedua jenis itu disatukan sehingga Anda tidak perlu memikirkannya lagi

Representasi seperti itu menghilangkan kesalahan integer overflow dan memberikan ilusi panjang bit tak terbatas, tetapi membutuhkan lebih banyak memori secara signifikan. Additionally, performing bignum arithmetic is slower than with fixed precision because it can’t run directly in hardware without an intermediate layer of emulation

Tantangan lain adalah mempertahankan perilaku operator bitwise yang konsisten di seluruh tipe bilangan bulat alternatif, yang sangat penting dalam menangani bit tanda. Ingatlah bahwa bilangan bulat presisi tetap di Python menggunakan representasi komplemen dua standar dari C, sedangkan bilangan bulat besar menggunakan magnitudo tanda

To mitigate that difference, Python will do the necessary binary conversion for you. It might change how a number is represented before and after applying a bitwise operator. Inilah komentar yang relevan dari kode sumber CPython, yang menjelaskan hal ini lebih detail

Operasi bitwise untuk angka negatif beroperasi seolah-olah pada representasi komplemen dua. Jadi ubah argumen dari magnitudo tanda menjadi komplemen dua, dan ubah hasilnya kembali menjadi magnitudo tanda di akhir. ()

Dengan kata lain, angka negatif diperlakukan sebagai urutan bit pelengkap dua saat Anda menerapkan operator bitwise padanya, meskipun hasilnya akan disajikan kepada Anda dalam bentuk besaran tanda. Ada beberapa cara untuk dan beberapa tipe unsigned di Python

Bit String dengan Python

Anda dipersilakan untuk menggunakan pena dan kertas di sepanjang sisa artikel ini. Bahkan bisa berfungsi sebagai latihan yang bagus. Namun, pada titik tertentu, Anda ingin memverifikasi apakah urutan biner atau string bit Anda sesuai dengan angka yang diharapkan di Python. Begini caranya

Mengubah >>> (42).bit_length() 6 _73 menjadi Biner

Untuk mengungkapkan bit yang membentuk bilangan bulat dengan Python, Anda dapat mencetak literal string yang diformat, yang secara opsional memungkinkan Anda menentukan jumlah nol di depan untuk ditampilkan

>>> ________40______8

Alternatifnya, Anda dapat memanggil

>>> (42).bit_length()
6
_86 dengan nomor tersebut sebagai argumen

>>>

>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
9

This global built-in function returns a string consisting of a binary literal, which starts with the prefix

>>> (42).bit_length()
6
87 and is followed by ones and zeros. Itu selalu menunjukkan jumlah digit minimum tanpa nol di depan

Anda juga dapat menggunakan literal seperti itu dalam kode Anda

>>>

if age >= 18 and not is_self_excluded:
    print("You can gamble")
0

Literal integer lain yang tersedia di Python adalah yang heksadesimal dan oktal, yang dapat Anda peroleh masing-masing dengan fungsi ________12______88 dan

>>> (42).bit_length()
6
89

>>>

if age >= 18 and not is_self_excluded:
    print("You can gamble")
1

Perhatikan bagaimana sistem heksadesimal, yang berbasis enam belas, memanfaatkan huruf

>>> (42).bit_length()
6
90 hingga
>>> (42).bit_length()
6
91 untuk menambah himpunan digit yang tersedia. Literal oktal dalam bahasa pemrograman lain biasanya diawali dengan nol biasa, yang mungkin membingungkan. Python secara eksplisit melarang literal semacam itu untuk menghindari kesalahan

>>>

if age >= 18 and not is_self_excluded:
    print("You can gamble")
2

Anda dapat mengekspresikan nilai yang sama dengan cara yang berbeda menggunakan salah satu literal bilangan bulat yang disebutkan

>>>

if age >= 18 and not is_self_excluded:
    print("You can gamble")
3

Pilih salah satu yang paling masuk akal dalam konteks. Misalnya, biasanya diekspresikan dengan notasi heksadesimal. Di sisi lain, literal oktal jarang terlihat akhir-akhir ini

Semua literal numerik dalam Python tidak peka huruf besar/kecil, jadi Anda bisa mengawalinya dengan huruf kecil atau huruf besar

>>>

if age >= 18 and not is_self_excluded:
    print("You can gamble")
4

Ini juga berlaku untuk literal bilangan titik-mengambang yang menggunakan notasi ilmiah serta literal bilangan kompleks

Remove ads

Konversi Biner ke >>> (42).bit_length() 6 73

Setelah string bit Anda siap, Anda bisa mendapatkan representasi desimalnya dengan memanfaatkan literal biner

>>>

if age >= 18 and not is_self_excluded:
    print("You can gamble")
5

Ini adalah cara cepat untuk melakukan konversi sambil bekerja di dalam interpreter Python interaktif. Sayangnya, itu tidak akan membiarkan Anda mengonversi urutan bit yang disintesis saat runtime karena semua literal harus dikodekan dalam kode sumber

Catatan. Anda mungkin tergoda untuk mengevaluasi kode Python dengan

>>> (42).bit_length()
6
93, tapi itu cara mudah untuk membahayakan keamanan program Anda, jadi jangan lakukan itu

Memanggil

>>> (42).bit_length()
6
_94 dengan dua argumen akan bekerja lebih baik dalam kasus string bit yang dihasilkan secara dinamis

>>>

if age >= 18 and not is_self_excluded:
    print("You can gamble")
6

Argumen pertama adalah rangkaian angka, sedangkan argumen kedua menentukan basis sistem angka. Tidak seperti literal biner, string bisa datang dari mana saja, bahkan pengguna mengetik di keyboard. Untuk melihat lebih dalam pada

>>> (42).bit_length()
6
_94, Anda dapat meluaskan kotak di bawah ini

Penggunaan Lain dari

>>> (42).bit_length()
6
94Tampilkan/Sembunyikan

Ada cara lain untuk menelepon

>>> (42).bit_length()
6
_94. Misalnya, mengembalikan nol saat dipanggil tanpa argumen

>>>

if age >= 18 and not is_self_excluded:
    print("You can gamble")
7

Fitur ini menjadikannya pola umum dalam koleksi

>>> (42).bit_length()
6
98, yang memerlukan penyedia nilai default. Ambil ini sebagai contoh

>>> ________44______8

Di sini,

>>> (42).bit_length()
6
_94 membantu menghitung kata dalam sebuah kalimat. Itu dipanggil secara otomatis setiap kali
>>> (42).bit_length()
6
_98 perlu menginisialisasi nilai kunci yang hilang dalam kamus

Penggunaan populer lainnya dari

>>> (42).bit_length()
6
94 adalah typecasting. Misalnya, saat Anda memberikan
>>> (42).bit_length()
6
_94 nilai floating-point, nilai tersebut akan dipotong dengan menghapus komponen pecahan

>>>

if age >= 18 and not is_self_excluded:
    print("You can gamble")
9

Saat Anda memberinya string, ia mencoba mengurai angka darinya

>>>

if age >= 18 & ~is_self_excluded:
    print("You can gamble")
0

Secara umum,

>>> (42).bit_length()
6
_94 akan menerima objek dari jenis apa pun asalkan itu mendefinisikan metode khusus yang dapat menangani konversi

Sejauh ini bagus. Tapi bagaimana dengan angka negatif?

Meniru Bit Tanda

Ketika Anda memanggil

>>> (42).bit_length()
6
86 pada bilangan bulat negatif, itu hanya menambahkan tanda minus ke string bit yang diperoleh dari nilai positif yang sesuai

>>>

if age >= 18 & ~is_self_excluded:
    print("You can gamble")
1

Mengubah tanda angka tidak memengaruhi string bit yang mendasarinya di Python. Sebaliknya, Anda diizinkan untuk mengawali string bit dengan tanda minus saat mengubahnya menjadi bentuk desimal

>>>

if age >= 18 & ~is_self_excluded:
    print("You can gamble")
2

Itu masuk akal di Python karena, secara internal, itu tidak menggunakan bit tanda. Anda dapat menganggap tanda bilangan bulat dengan Python sebagai informasi yang disimpan secara terpisah dari modulus

Namun, ada beberapa solusi yang memungkinkan Anda meniru urutan bit dengan panjang tetap yang berisi bit tanda

  • Bitmask
  • Modulo operation (
    >>> (42).bit_length()
    6
    
    39)
  • >>> (42).bit_length()
    6
    
    58 modul
  • >>> len("€uro".encode("utf-8"))
    6
    
    07 modul
  • >>> len("€uro".encode("utf-8"))
    6
    
    08 modul

Anda tahu dari bagian sebelumnya bahwa untuk memastikan panjang bit tertentu dari suatu angka, Anda dapat menggunakan bitmask yang bagus. Misalnya, untuk menyimpan satu byte, Anda dapat menggunakan topeng yang terdiri dari tepat delapan bit yang dihidupkan

>>>

if age >= 18 & ~is_self_excluded:
    print("You can gamble")
3

Masking memaksa Python untuk sementara mengubah representasi angka dari magnitudo tanda menjadi komplemen dua, lalu kembali lagi. Jika Anda lupa tentang nilai desimal dari literal biner yang dihasilkan, yaitu sama dengan 21410, maka itu akan mewakili -4210 dalam komplemen dua. Bit paling kiri akan menjadi bit tanda

Alternatifnya, Anda dapat memanfaatkan operasi modulo yang Anda gunakan sebelumnya untuk mensimulasikan pergeseran kanan logis di Python

>>>

if age >= 18 & ~is_self_excluded:
    print("You can gamble")
4

Jika itu terlihat terlalu berbelit-belit untuk selera Anda, maka Anda dapat menggunakan salah satu modul dari pustaka standar yang menyatakan maksud yang sama dengan lebih jelas. Misalnya, menggunakan

>>> (42).bit_length()
6
_58 akan memiliki efek yang sama

>>>

if age >= 18 & ~is_self_excluded:
    print("You can gamble")
5

Anda pernah melihatnya sebelumnya, tetapi hanya sebagai pengingat, itu akan membonceng tipe integer yang tidak ditandatangani dari C

Modul standar lain yang dapat Anda gunakan untuk konversi semacam ini dengan Python adalah modul

>>> len("€uro".encode("utf-8"))
6
07. Ini mendefinisikan struktur data yang mirip dengan
>>> len("€uro".encode("utf-8"))
6
11 tetapi hanya diperbolehkan untuk menampung elemen dengan tipe numerik yang sama. Saat mendeklarasikan array, Anda perlu menunjukkan tipenya di depan dengan huruf yang sesuai

>>>

if age >= 18 & ~is_self_excluded:
    print("You can gamble")
6

Misalnya,

>>> len("€uro".encode("utf-8"))
6
_12 berarti byte bertanda 8-bit, sedangkan
>>> len("€uro".encode("utf-8"))
6
13 berarti padanannya yang tidak bertanda. Ada beberapa tipe standar lainnya, seperti bilangan bulat 16-bit yang ditandatangani atau angka floating-point 32-bit

Menyalin byte mentah di antara dua larik ini mengubah cara bit diinterpretasikan. Namun, dibutuhkan dua kali jumlah memori, yang cukup boros. Untuk melakukan sedikit penulisan ulang di tempat, Anda dapat mengandalkan modul

>>> len("€uro".encode("utf-8"))
6
08 , yang menggunakan set serupa untuk deklarasi tipe

>>>

if age >= 18 & ~is_self_excluded:
    print("You can gamble")
7

Pengepakan memungkinkan Anda meletakkan objek di memori sesuai dengan penentu tipe data C yang diberikan. Ini mengembalikan objek hanya-baca, yang berisi byte mentah dari blok memori yang dihasilkan. Nanti, Anda dapat membaca kembali byte tersebut menggunakan kumpulan kode jenis yang berbeda untuk mengubah cara mereka diterjemahkan ke dalam objek Python

Sampai saat ini, Anda telah menggunakan teknik yang berbeda untuk mendapatkan string bilangan bulat dengan panjang tetap yang diekspresikan dalam representasi komplemen dua. Jika Anda ingin mengonversi jenis urutan bit ini kembali ke bilangan bulat Python, maka Anda dapat mencoba fungsi ini

if age >= 18 & ~is_self_excluded:
    print("You can gamble")
8

Fungsi menerima string yang terdiri dari digit biner. Pertama, ini mengubah digit menjadi bilangan bulat unsigned, mengabaikan bit tanda. Selanjutnya, ia menggunakan dua bitmask untuk mengekstrak bit tanda dan magnitudo, yang lokasinya bergantung pada panjang bit yang ditentukan. Akhirnya, menggabungkan mereka menggunakan aritmatika biasa, mengetahui bahwa nilai yang terkait dengan bit tanda adalah negatif

Anda dapat mencobanya dengan string bit lama tepercaya dari contoh sebelumnya

>>>

if age >= 18 & ~is_self_excluded:
    print("You can gamble")
9

>>> (42).bit_length()
6
_94 Python memperlakukan semua bit sebagai besarnya, jadi tidak ada kejutan di sana. Namun, fungsi baru ini mengasumsikan string panjang 32-bit secara default, yang berarti bit tanda secara implisit sama dengan nol untuk string yang lebih pendek. Saat Anda meminta panjang bit yang cocok dengan string bit Anda, maka Anda akan mendapatkan hasil yang diharapkan

Meskipun bilangan bulat adalah tipe data yang paling tepat untuk bekerja dengan operator bitwise dalam banyak kasus, terkadang Anda perlu mengekstraksi dan memanipulasi fragmen data biner terstruktur, seperti piksel gambar. Modul

>>> len("€uro".encode("utf-8"))
6
_07 dan
>>> len("€uro".encode("utf-8"))
6
08 secara singkat menyentuh topik ini, jadi Anda akan menjelajahinya lebih detail selanjutnya

Melihat Data dalam Biner

Anda tahu cara membaca dan menafsirkan byte individual. Namun, data dunia nyata seringkali terdiri dari lebih dari satu byte untuk menyampaikan informasi. Ambil tipe data

>>> (42).bit_length()
6
_68 sebagai contoh. Satu angka floating-point dalam Python menempati sebanyak delapan byte dalam memori

Bagaimana Anda melihat byte itu?

Anda tidak bisa begitu saja menggunakan operator bitwise karena tidak bekerja dengan bilangan floating-point

>>>

>>> age = 18
>>> is_self_excluded = True
>>> age >= 18 & ~is_self_excluded  # Bitwise logical operators
True
>>> age >= 18 and not is_self_excluded  # Logical operators
False
0

Anda harus melupakan jenis data tertentu yang Anda hadapi dan memikirkannya dalam bentuk aliran byte umum. Dengan begitu, tidak masalah apa yang diwakili oleh byte di luar konteks mereka diproses oleh operator bitwise

Untuk mendapatkan

>>> len("€uro".encode("utf-8"))
6
15 dari angka floating-point dengan Python, Anda dapat mengemasnya menggunakan modul
>>> len("€uro".encode("utf-8"))
6
08 yang sudah dikenal

>>>

>>> age = 18
>>> is_self_excluded = True
>>> age >= 18 & ~is_self_excluded  # Bitwise logical operators
True
>>> age >= 18 and not is_self_excluded  # Logical operators
False
1

Abaikan karakter format yang melewati argumen pertama. Mereka tidak akan masuk akal sampai Anda masuk ke bagian di bawah ini. Di balik representasi tekstual yang agak kabur ini menyembunyikan daftar delapan bilangan bulat

>>>

>>> age = 18
>>> is_self_excluded = True
>>> age >= 18 & ~is_self_excluded  # Bitwise logical operators
True
>>> age >= 18 and not is_self_excluded  # Logical operators
False
2

Nilainya sesuai dengan byte berikutnya yang digunakan untuk mewakili angka titik-mengambang dalam biner. Anda dapat menggabungkannya untuk menghasilkan string bit yang sangat panjang

>>>

>>> age = 18
>>> is_self_excluded = True
>>> age >= 18 & ~is_self_excluded  # Bitwise logical operators
True
>>> age >= 18 and not is_self_excluded  # Logical operators
False
3

64 bit ini adalah tanda, eksponen, dan mantissa dengan presisi ganda yang Anda baca sebelumnya. Untuk mensintesis

>>> (42).bit_length()
6
_68 dari string bit yang serupa, Anda dapat membalik prosesnya

>>>

>>> age = 18
>>> is_self_excluded = True
>>> age >= 18 & ~is_self_excluded  # Bitwise logical operators
True
>>> age >= 18 and not is_self_excluded  # Logical operators
False
4

>>> len("€uro".encode("utf-8"))
6
23 mengembalikan tuple karena memungkinkan Anda membaca lebih dari satu nilai sekaligus. Misalnya, Anda dapat membaca string bit yang sama dengan empat bilangan bulat bertanda 16-bit

>>>

>>> age = 18
>>> is_self_excluded = True
>>> age >= 18 & ~is_self_excluded  # Bitwise logical operators
True
>>> age >= 18 and not is_self_excluded  # Logical operators
False
5

Seperti yang Anda lihat, cara interpretasi bit string harus diketahui sebelumnya untuk menghindari berakhir dengan data yang kacau. Satu pertanyaan penting yang perlu Anda tanyakan pada diri sendiri adalah dari mana akhir aliran byte Anda harus mulai membaca—kiri atau kanan. Baca terus untuk mencari tahu

Urutan Byte

There’s no dispute about the order of bits in a single byte. Anda akan selalu menemukan bit paling tidak signifikan pada indeks nol dan bit paling signifikan pada indeks tujuh, terlepas dari bagaimana mereka ditata secara fisik dalam memori. Operator pergeseran bitwise mengandalkan konsistensi ini

Namun, tidak ada konsensus untuk urutan byte dalam potongan data multibyte. Sepotong informasi yang terdiri lebih dari satu byte dapat dibaca dari kiri ke kanan seperti teks bahasa Inggris atau dari kanan ke kiri seperti bahasa Arab, misalnya. Computers see bytes in a binary stream like humans see words in a sentence

Tidak masalah dari arah mana komputer memilih untuk membaca byte selama mereka menerapkan aturan yang sama di mana-mana. Sayangnya, arsitektur komputer yang berbeda menggunakan pendekatan yang berbeda, yang membuat transfer data di antara mereka menjadi sulit

Big-Endian vs Little-Endian

Mari kita ambil bilangan bulat 32-bit unsigned yang sesuai dengan angka 196910, yang merupakan tahun ketika Monty Python pertama kali muncul di TV. Dengan semua nol di depannya, ia memiliki representasi biner berikut 000000000000000000000111101100012

Bagaimana Anda menyimpan nilai seperti itu di memori komputer?

Jika Anda membayangkan memori sebagai pita satu dimensi yang terdiri dari byte, maka Anda perlu memecah data tersebut menjadi byte individual dan mengaturnya dalam blok yang berdekatan. Beberapa merasa wajar untuk memulai dari ujung kiri karena begitulah cara mereka membaca, sementara yang lain lebih suka memulai dari ujung kanan

Urutan Byte Alamat N Alamat N+1 Alamat N+2 Alamat N+3 Big-Endian000000002000000002000001112101100012 Little-Endian101100012000001112000000002000000002

Ketika byte ditempatkan dari kiri ke kanan, byte yang paling signifikan ditugaskan ke alamat memori terendah. Ini dikenal sebagai tatanan big-endian. Sebaliknya, ketika byte disimpan dari kanan ke kiri, byte yang paling tidak signifikan didahulukan. Itu disebut pesanan little-endian

Catatan. Nama-nama lucu ini terinspirasi dari novel Gulliver's Travels abad ke-18 karya Jonathan Swift. Penulis menggambarkan konflik antara Little-Endians dan Big-Endians mengenai cara yang benar untuk memecahkan cangkang telur rebus. Sementara Little-Endian lebih suka memulai dengan ujung kecil yang runcing, Big-Endian lebih menyukai ujung yang besar

Cara mana yang lebih baik?

Dari sudut pandang praktis, tidak ada keuntungan nyata menggunakan salah satunya. Mungkin ada beberapa keuntungan kecil dalam kinerja di tingkat perangkat keras, tetapi Anda tidak akan menyadarinya. Protokol jaringan utama menggunakan urutan big-endian, yang memungkinkan mereka memfilter paket data lebih cepat mengingat desain hierarki pengalamatan IP. Selain itu, beberapa orang mungkin merasa lebih nyaman bekerja dengan urutan byte tertentu saat melakukan debug

Either way, jika Anda tidak melakukannya dengan benar dan mencampuradukkan kedua standar, maka hal buruk mulai terjadi

>>>

>>> age = 18
>>> is_self_excluded = True
>>> age >= 18 & ~is_self_excluded  # Bitwise logical operators
True
>>> age >= 18 and not is_self_excluded  # Logical operators
False
6

Saat Anda membuat serial beberapa nilai ke aliran byte menggunakan satu konvensi dan mencoba membacanya kembali dengan yang lain, Anda akan mendapatkan hasil yang sama sekali tidak berguna. Skenario ini kemungkinan besar terjadi saat data dikirim melalui jaringan, tetapi Anda juga dapat mengalaminya saat membaca file lokal dalam format tertentu. Misalnya, header bitmap Windows selalu menggunakan little-endian, sedangkan JPEG dapat menggunakan kedua urutan byte tersebut

Endianness Asli

Untuk mengetahui endianness platform Anda, Anda dapat menggunakan modul

>>> len("€uro".encode("utf-8"))
6
24

>>>

>>> age = 18
>>> is_self_excluded = True
>>> age >= 18 & ~is_self_excluded  # Bitwise logical operators
True
>>> age >= 18 and not is_self_excluded  # Logical operators
False
7

Anda tidak dapat mengubah endianness, karena ini adalah fitur intrinsik dari arsitektur CPU Anda. Tidak mungkin untuk mengejeknya untuk tujuan pengujian tanpa virtualisasi perangkat keras seperti QEMU, jadi bahkan VirtualBox yang populer pun tidak akan membantu

Khususnya, keluarga prosesor x86 dari Intel dan AMD, yang menggerakkan sebagian besar laptop dan desktop modern, adalah produk kecil. Perangkat seluler didasarkan pada arsitektur ARM berenergi rendah, sementara beberapa arsitektur lama seperti Motorola 68000 kuno hanya merupakan arsitektur big-endian

Untuk informasi tentang menentukan endianness dalam C, perluas kotak di bawah ini

Memeriksa Urutan Byte di CTampilkan/Sembunyikan

Secara historis, cara untuk mendapatkan endianness mesin Anda di C adalah dengan mendeklarasikan bilangan bulat kecil dan kemudian membaca byte pertamanya dengan sebuah pointer

>>> age = 18
>>> is_self_excluded = True
>>> age >= 18 & ~is_self_excluded  # Bitwise logical operators
True
>>> age >= 18 and not is_self_excluded  # Logical operators
False
_8

Jika nilainya keluar lebih tinggi dari nol, maka byte yang disimpan di alamat memori terendah harus menjadi yang paling tidak signifikan

Setelah Anda mengetahui endianness asli mesin Anda, Anda ingin mengonversi antara urutan byte yang berbeda saat memanipulasi data biner. Cara universal untuk melakukannya, terlepas dari tipe data yang ada, adalah membalikkan objek

>>> len("€uro".encode("utf-8"))
6
15 generik atau urutan bilangan bulat yang mewakili byte tersebut

>>>

>>> age = 18
>>> is_self_excluded = True
>>> age >= 18 & ~is_self_excluded  # Bitwise logical operators
True
>>> age >= 18 and not is_self_excluded  # Logical operators
False
9

Namun, seringkali lebih mudah menggunakan modul

>>> len("€uro".encode("utf-8"))
6
08, yang memungkinkan Anda menentukan tipe data C standar. Selain itu, ini memungkinkan Anda untuk meminta urutan byte yang diberikan dengan pengubah opsional

>>>

>>> age >= (18 & ~is_self_excluded)
True
0

Tanda lebih besar dari (

>>> len("€uro".encode("utf-8"))
6
_27) menunjukkan bahwa byte ditata dalam urutan big-endian, sedangkan simbol kurang dari (
>>> len("€uro".encode("utf-8"))
6
28) sesuai dengan little-endian. Jika Anda tidak menentukannya, maka native endianness diasumsikan. Ada beberapa pengubah lagi, seperti tanda seru (
>>> len("€uro".encode("utf-8"))
6
29), yang menandakan urutan byte jaringan

Urutan Byte Jaringan

Jaringan komputer terbuat dari perangkat yang heterogen seperti laptop, desktop, tablet, smartphone, dan bahkan bola lampu yang dilengkapi dengan adaptor Wi-Fi. Mereka semua membutuhkan protokol dan standar yang disepakati, termasuk urutan byte untuk transmisi biner, untuk berkomunikasi secara efektif

Di awal Internet, diputuskan bahwa urutan byte untuk protokol jaringan tersebut akan menjadi big-endian

Program yang ingin berkomunikasi melalui jaringan dapat mengambil C API klasik, yang mengabstraksi detail seluk beluk dengan lapisan soket. Python membungkus API itu melalui modul

>>> len("€uro".encode("utf-8"))
6
30 bawaan. Namun, kecuali Anda menulis protokol biner khusus, Anda mungkin ingin memanfaatkan abstraksi tingkat yang lebih tinggi, seperti protokol HTTP, yang berbasis teks

Di mana modul

>>> len("€uro".encode("utf-8"))
6
30 dapat berguna adalah dalam konversi urutan byte. Itu memperlihatkan beberapa fungsi dari C API, dengan nama mereka yang khas dan membingungkan

>>>

>>> age >= (18 & ~is_self_excluded)
True
1

Jika host Anda sudah menggunakan urutan byte big-endian, maka tidak ada yang perlu dilakukan. Nilainya akan tetap sama

Bitmask

Bitmask berfungsi seperti stensil grafiti yang menghalangi cat agar tidak disemprotkan ke area permukaan tertentu. Ini memungkinkan Anda mengisolasi bit untuk menerapkan beberapa fungsi padanya secara selektif. Bitmasking melibatkan operator logis bitwise dan operator shift bitwise yang telah Anda baca

Anda dapat menemukan bitmask dalam banyak konteks berbeda. Misalnya, subnet mask dalam pengalamatan IP sebenarnya adalah bitmask yang membantu Anda mengekstrak alamat jaringan. Saluran piksel, yang sesuai dengan warna merah, hijau, dan biru dalam model RGB, dapat diakses dengan bitmask. Anda juga dapat menggunakan bitmask untuk menentukan bendera Boolean yang kemudian dapat Anda kemas di bidang bit

Ada beberapa jenis operasi umum yang terkait dengan bitmask. Anda akan melihat sekilas beberapa di antaranya di bawah ini

Mendapatkan Sedikit

Untuk membaca nilai bit tertentu pada posisi tertentu, Anda dapat menggunakan bitwise AND terhadap bitmask yang hanya terdiri dari satu bit pada indeks yang diinginkan.

>>>

>>> age >= (18 & ~is_self_excluded)
True
2

The mask will suppress all bits except for the one that you’re interested in. It’ll result in either zero or a power of two with an exponent equal to the bit index. If you’d like to get a simple yes-or-no answer instead, then you could shift to the right and check the least-significant bit

>>>

>>> age >= (18 & ~is_self_excluded)
True
3

Kali ini, ini akan menormalkan nilai bit sehingga tidak pernah melebihi satu. Anda kemudian dapat menggunakan fungsi itu untuk mendapatkan nilai Boolean

>>> (42).bit_length()
6
28 atau
>>> (42).bit_length()
6
29 daripada nilai numerik

Mengatur Sedikit

Setting a bit is similar to getting one. You take advantage of the same bitmask as before, but instead of using bitwise AND, you use the bitwise OR operator

>>>

>>> age >= (18 & ~is_self_excluded)
True
4

Topeng mempertahankan semua bit asli sambil menerapkan bit biner pada indeks yang ditentukan. Had that bit already been set, its value wouldn’t have changed

Menghapus Sedikit

To clear a bit, you want to copy all binary digits while enforcing zero at one specific index. You can achieve this effect by using the same bitmask once again, but in the inverted form

>>>

>>> age >= (18 & ~is_self_excluded)
True
5

Using the bitwise NOT on a positive number always produces a negative value in Python. Meskipun ini umumnya tidak diinginkan, tidak masalah di sini karena Anda segera menerapkan operator AND bitwise. This, in turn, triggers the mask’s conversion to two’s complement representation, which gets you the expected result

Toggling a Bit

Terkadang berguna untuk dapat mengaktifkan dan menonaktifkan sedikit lagi secara berkala. That’s a perfect opportunity for the bitwise XOR operator, which can flip your bit like that

>>>

>>> age >= (18 & ~is_self_excluded)
True
6

Perhatikan bitmask yang sama digunakan lagi. A binary one on the specified position will make the bit at that index invert its value. Memiliki nol biner di tempat yang tersisa akan memastikan bahwa sisa bit akan disalin

Kelebihan Operator Bitwise

Domain utama operator bitwise adalah bilangan bulat. That’s where they make the most sense. However, you’ve also seen them used in a Boolean context, in which they replaced the logical operators. Python provides alternative implementations for some of its operators and lets you overload them for new data types

Meskipun proposal untuk membebani operator logis dengan Python ditolak, Anda dapat memberikan arti baru ke salah satu operator bitwise. Many popular libraries, and even the standard library, take advantage of it

Tipe Data Bawaan

Operator bitwise Python ditentukan untuk tipe data bawaan berikut

  • >>> (42).bit_length()
    6
    
    _73
  • >>> len("€uro".encode("utf-8"))
    6
    
    _35
  • >>> len("€uro".encode("utf-8"))
    6
    
    36 and
  • >>> len("€uro".encode("utf-8"))
    6
    
    38 (sejak Python 3. 9)

Ini bukan fakta yang diketahui secara luas, tetapi operator bitwise dapat melakukan operasi dari aljabar himpunan, seperti penyatuan, perpotongan, dan perbedaan simetris, serta menggabungkan dan memperbarui kamus

Note. At the time of writing, Python 3. 9 hadn’t been released, but you could take a sneak peek at the upcoming language features using Docker or pyenv

Ketika

>>> (42).bit_length()
6
_31 dan
>>> (42).bit_length()
6
32 adalah set Python, maka operator bitwise sesuai dengan metode berikut

Set MethodBitwise Operator

>>> len("€uro".encode("utf-8"))
6
41
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
4
>>> len("€uro".encode("utf-8"))
6
43
>>> (42).bit_length()
6
09
>>> len("€uro".encode("utf-8"))
6
45
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
2
>>> len("€uro".encode("utf-8"))
6
47
>>> (42).bit_length()
6
06
>>> len("€uro".encode("utf-8"))
6
49
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
6
>>> len("€uro".encode("utf-8"))
6
51
>>> (42).bit_length()
6
12

Mereka melakukan hal yang hampir sama, jadi terserah Anda sintaks mana yang akan digunakan. Apart from that, there’s also an overloaded minus operator (

>>> (42).bit_length()
6
64), which implements a difference of two sets. To see them in action, assume you have the following two sets of fruits and vegetables

>>>

>>> age >= (18 & ~is_self_excluded)
True
7

Mereka berbagi satu anggota yang sama, yang sulit untuk diklasifikasikan, tetapi elemen lainnya terpisah

One thing to watch out for is the immutable

>>> len("€uro".encode("utf-8"))
6
54, which is missing the methods for in-place updates. Namun, ketika Anda menggunakan rekan operator bitwise mereka, artinya sedikit berbeda

>>> ________49______8

It looks like

>>> len("€uro".encode("utf-8"))
6
54 isn’t so immutable after all when you use the bitwise operators, but the devil is in the details. Here’s what actually happens

>>> age >= (18 & ~is_self_excluded)
True
_9

Alasan ini berfungsi untuk kedua kalinya adalah karena Anda tidak mengubah objek asli yang tidak dapat diubah. Instead, you create a new one and assign it to the same variable again

Python

>>> len("€uro".encode("utf-8"))
6
_38 hanya mendukung bitwise OR, yang berfungsi seperti operator gabungan. You can use it to update a dictionary in place or merge two dictionaries into a new one

>>>

>>> (age >= 18) & ~is_self_excluded
0
0

Versi tambahan dari operator bitwise setara dengan

>>> len("€uro".encode("utf-8"))
6
57

Third-Party Modules

Banyak pustaka populer, termasuk NumPy, panda, dan SQLAlchemy, membebani operator bitwise untuk tipe data spesifiknya. Ini adalah tempat yang paling mungkin Anda akan menemukan operator bitwise di Python karena mereka tidak lagi sering digunakan dalam arti aslinya.

For example, NumPy applies them to vectorized data in a pointwise fashion

>>>

>>> (age >= 18) & ~is_self_excluded
0
1

This way, you don’t need to manually apply the same bitwise operator to each element of the array. But you can’t do the same thing with ordinary lists in Python

pandas uses NumPy behind the scenes, and it also provides overloaded versions of the bitwise operators for its

>>> len("€uro".encode("utf-8"))
6
58 and
>>> len("€uro".encode("utf-8"))
6
59 objects. Namun, mereka berperilaku seperti yang Anda harapkan. Satu-satunya perbedaan adalah bahwa mereka melakukan pekerjaan biasa pada vektor dan matriks angka, bukan pada skalar individu

Hal-hal menjadi lebih menarik dengan perpustakaan yang memberikan operator bitwise arti yang sama sekali baru. Misalnya, SQLAlchemy menyediakan sintaks ringkas untuk menanyakan database

>>> (age >= 18) & ~is_self_excluded
0
_2

Operator bitwise AND (

>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
1) pada akhirnya akan menerjemahkan ke bagian kueri SQL. Namun, itu tidak terlalu jelas, setidaknya tidak untuk IDE saya, yang mengeluh tentang penggunaan operator bitwise yang tidak sehat ketika melihat mereka dalam jenis ekspresi ini. It immediately suggests replacing every occurrence of
>>> def call(x):
..     print(f"call({x=})")
..     return x
...
>>> call(False) or call(True)  # Both operands evaluated
call(x=False)
call(x=True)
True
>>> call(True) or call(False)  # Only the left operand evaluated
call(x=True)
True
1 with a logical
>>> (42).bit_length()
6
25, not knowing that doing so would make the code stop working

This type of operator overloading is a controversial practice that relies on implicit magic you have to know up front. Beberapa bahasa pemrograman seperti Java mencegah penyalahgunaan seperti itu dengan melarang sama sekali kelebihan beban operator. Python lebih liberal dalam hal itu dan percaya bahwa Anda tahu apa yang Anda lakukan

Jenis Data Kustom

Untuk menyesuaikan perilaku operator bitwise Python, Anda harus mendefinisikan sebuah kelas dan kemudian mengimplementasikan yang sesuai di dalamnya. Pada saat yang sama, Anda tidak dapat mendefinisikan ulang perilaku operator bitwise untuk jenis yang sudah ada. Kelebihan beban operator hanya mungkin terjadi pada tipe data baru

Berikut adalah ikhtisar singkat tentang metode khusus yang memungkinkan Anda membebani operator bitwise

Magic MethodExpression

>>> len("€uro".encode("utf-8"))
6
63
>>> len("€uro".encode("utf-8"))
6
64
>>> len("€uro".encode("utf-8"))
6
65
>>> len("€uro".encode("utf-8"))
6
66
>>> len("€uro".encode("utf-8"))
6
67
>>> len("€uro".encode("utf-8"))
6
68
>>> len("€uro".encode("utf-8"))
6
69
>>> len("€uro".encode("utf-8"))
6
70
>>> len("€uro".encode("utf-8"))
6
71
>>> len("€uro".encode("utf-8"))
6
72
>>> len("€uro".encode("utf-8"))
6
73
>>> len("€uro".encode("utf-8"))
6
74
>>> len("€uro".encode("utf-8"))
6
75
>>> len("€uro".encode("utf-8"))
6
76
>>> len("€uro".encode("utf-8"))
6
77
>>> len("€uro".encode("utf-8"))
6
78
>>> len("€uro".encode("utf-8"))
6
79
>>> len("€uro".encode("utf-8"))
6
80
>>> len("€uro".encode("utf-8"))
6
81
>>> len("€uro".encode("utf-8"))
6
82
>>> len("€uro".encode("utf-8"))
6
83
>>> len("€uro".encode("utf-8"))
6
84
>>> len("€uro".encode("utf-8"))
6
85
>>> len("€uro".encode("utf-8"))
6
86
>>> len("€uro".encode("utf-8"))
6
87
>>> len("€uro".encode("utf-8"))
6
88
>>> len("€uro".encode("utf-8"))
6
89
>>> len("€uro".encode("utf-8"))
6
90
>>> len("€uro".encode("utf-8"))
6
91
>>> len("€uro".encode("utf-8"))
6
92
>>> len("€uro".encode("utf-8"))
6
93
>>> len("€uro".encode("utf-8"))
6
94

Anda tidak perlu mendefinisikan semuanya. Misalnya, untuk memiliki sintaks yang sedikit lebih nyaman untuk menambahkan dan menambahkan elemen ke a , cukup menerapkan hanya

>>> len("€uro".encode("utf-8"))
6
95 dan
>>> len("€uro".encode("utf-8"))
6
96

>>>

>>> (age >= 18) & ~is_self_excluded
0
3

Kelas yang ditentukan pengguna ini membungkus deque untuk menggunakan kembali implementasinya dan menambahnya dengan dua metode tambahan yang memungkinkan untuk menambahkan item ke ujung kiri atau kanan koleksi

Steganografi Bit Paling Tidak Signifikan

Wah, itu banyak yang harus diproses. Jika Anda masih bingung, bertanya-tanya mengapa Anda ingin menggunakan operator bitwise, maka jangan khawatir. Saatnya menunjukkan apa yang dapat Anda lakukan dengan mereka dengan cara yang menyenangkan

Untuk mengikuti contoh di bagian ini, Anda dapat mengunduh kode sumber dengan mengklik tautan di bawah ini

Dapatkan Kode Sumber. Click here to get the source code you’ll use to learn about Python’s bitwise operators in this tutorial

Anda akan belajar tentang steganografi dan menerapkan konsep ini untuk menyematkan file arbitrer secara diam-diam dalam gambar bitmap

Kriptografi vs Steganografi

Kriptografi adalah tentang mengubah pesan menjadi pesan yang hanya dapat dibaca oleh mereka yang memiliki kunci yang tepat. Semua orang masih dapat melihat pesan terenkripsi, tetapi itu tidak masuk akal bagi mereka. Salah satu bentuk kriptografi pertama adalah cipher substitusi, seperti yang dinamai Julius Caesar

Steganografi mirip dengan kriptografi karena juga memungkinkan Anda berbagi pesan rahasia dengan audiens yang Anda inginkan. Namun, alih-alih menggunakan enkripsi, ia dengan cerdik menyembunyikan informasi di media yang tidak menarik perhatian. Contohnya termasuk menggunakan tinta tak terlihat atau menulis akrostik di mana huruf pertama dari setiap kata atau baris membentuk pesan rahasia

Kecuali Anda tahu bahwa pesan rahasia disembunyikan dan metode untuk memulihkannya, Anda mungkin akan mengabaikan operatornya. Anda dapat menggabungkan kedua teknik agar lebih aman, menyembunyikan pesan terenkripsi daripada yang asli

Ada banyak cara untuk menyelundupkan data rahasia di dunia digital. Secara khusus, format file yang membawa banyak data, seperti file audio, video, atau gambar, sangat cocok karena memberi Anda banyak ruang untuk bekerja. Perusahaan yang merilis materi berhak cipta mungkin menggunakan steganografi untuk menandai salinan individual dan melacak sumber kebocoran, misalnya

Di bawah, Anda akan menyuntikkan data rahasia ke bitmap biasa, yang mudah dibaca dan ditulis dengan Python tanpa memerlukan ketergantungan eksternal

Berformat File Bitmap

Kata bitmap biasanya mengacu pada format file Windows bitmap (

>>> len("€uro".encode("utf-8"))
6
97), yang mendukung beberapa cara alternatif untuk merepresentasikan piksel. To make life easier, you’re going to assume that pixels are stored in 24-bit uncompressed RGB (red, green, and blue) format. Piksel akan memiliki tiga saluran warna yang masing-masing dapat menyimpan nilai dari 010 hingga 25510

Setiap bitmap dimulai dengan header file, yang berisi metadata seperti lebar dan tinggi gambar. Berikut adalah beberapa bidang yang menarik dan posisinya relatif terhadap awal tajuk

FieldByte OffsetBytes LengthTypeSample ValueSignature

>>> len("€uro".encode("utf-8"))
6
982StringBMFile Size
>>> len("€uro".encode("utf-8"))
6
994Unsigned int7,629,186Reserved #1
>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
002Bytes0Reserved #2
>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
012Bytes0Pixels Offset
>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
024Unsigned int122Pixels Size
>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
034Unsigned int7,629,064Image Width
>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
044Unsigned int1,954Image Height
>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
054Unsigned int1,301Bits Per Pixel
>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
062Unsigned short24Compression
>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
074Unsigned int0Colors Palette
>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
084Unsigned int0

You can infer from this header that the corresponding bitmap is 1,954 pixels wide and 1,301 pixels high. Itu tidak menggunakan kompresi, juga tidak memiliki palet warna. Setiap piksel menempati 24 bit, atau 3 byte, dan data piksel mentah dimulai pada offset 12210

Anda dapat membuka bitmap dalam mode biner, mencari offset yang diinginkan, membaca jumlah byte yang diberikan, dan membatalkan serialisasi menggunakan

>>> len("€uro".encode("utf-8"))
6
08 seperti sebelumnya

>>> (age >= 18) & ~is_self_excluded
0
_4

Perhatikan bahwa semua bidang bilangan bulat dalam bitmap disimpan dalam urutan byte little-endian

Anda mungkin telah melihat perbedaan kecil antara jumlah byte piksel yang dinyatakan di header dan yang akan dihasilkan dari ukuran gambar. Saat Anda mengalikan 1.954 piksel × 1.301 piksel × 3 byte, Anda mendapatkan nilai 2.602 byte kurang dari 7.629.064

Ini karena byte piksel diisi dengan nol sehingga setiap baris merupakan kelipatan empat byte. Jika lebar gambar dikalikan tiga byte merupakan kelipatan empat, maka padding tidak diperlukan. Jika tidak, byte kosong ditambahkan di akhir setiap baris

Catatan. Untuk menghindari timbulnya kecurigaan, Anda harus mempertimbangkan bantalan itu dengan melewatkan byte kosong. Kalau tidak, itu akan menjadi hadiah yang jelas bagi seseorang yang tahu apa yang harus dicari

Bitmap menyimpan baris piksel secara terbalik, mulai dari bawah, bukan dari atas. Juga, setiap piksel diserialisasi ke vektor saluran warna dalam urutan BGR yang agak aneh daripada RGB. Namun, ini tidak relevan dengan tugas menyembunyikan data rahasia

Bitwise Hide and Seek

Anda dapat menggunakan operator bitwise untuk menyebarkan data khusus melalui byte piksel berurutan. Idenya adalah untuk menimpa bit yang paling tidak signifikan di masing-masingnya dengan bit yang berasal dari byte rahasia berikutnya. Ini akan menghasilkan paling sedikit noise, tetapi Anda dapat bereksperimen dengan menambahkan lebih banyak bit untuk mencapai keseimbangan antara ukuran data yang disuntikkan dan distorsi piksel

Catatan. Menggunakan steganografi bit paling tidak signifikan tidak memengaruhi ukuran file dari bitmap yang dihasilkan. It’ll remain the same as the original file

Dalam beberapa kasus, bit yang sesuai akan sama, sehingga tidak ada perubahan nilai piksel apa pun. However, even in the worst-case scenario, a pixel color will differ only by a fraction of a percent. Anomali sekecil itu akan tetap tidak terlihat oleh mata manusia tetapi dapat dideteksi dengan steganalisis, yang menggunakan statistik

Lihatlah gambar-gambar yang dipotong ini

Apa itu shift kiri dan shift kanan di python?

Yang di sebelah kiri berasal dari bitmap asli, sedangkan gambar di sebelah kanan menggambarkan bitmap yang diproses dengan video tersemat yang disimpan pada bit yang paling tidak signifikan. Bisakah Anda melihat perbedaannya?

Sepotong kode berikut menyandikan data rahasia ke bitmap

>>> (age >= 18) & ~is_self_excluded
0
5

Untuk setiap byte data rahasia dan delapan byte data piksel yang sesuai, tidak termasuk byte pad, ia menyiapkan daftar bit untuk disebarkan. Selanjutnya, itu menimpa bit paling tidak signifikan di masing-masing dari delapan byte menggunakan bitmask yang relevan. The result is converted to a

>>> len("€uro".encode("utf-8"))
6
15 object and assigned back to the part of the bitmap that it originally came from

Untuk mendekode file dari bitmap yang sama, Anda perlu mengetahui berapa banyak byte rahasia yang ditulis padanya. Anda dapat mengalokasikan beberapa byte di awal aliran data untuk menyimpan nomor ini, atau Anda dapat menggunakan bidang yang dicadangkan dari header bitmap

>>> (age >= 18) & ~is_self_excluded
0
6

Ini melompat ke offset kanan dalam file, membuat serial Python

>>> (42).bit_length()
6
73 ke byte mentah, dan menuliskannya

Anda mungkin juga ingin menyimpan nama file rahasia Anda. Karena dapat memiliki panjang yang sewenang-wenang, masuk akal untuk membuat cerita bersambung menggunakan string yang diakhiri null, yang akan mendahului konten file. Untuk membuat string seperti itu, Anda perlu menyandikan objek Python

>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
12 ke byte dan secara manual menambahkan byte nol di bagian akhir

>>>

>>> (age >= 18) & ~is_self_excluded
0
7

Also, it doesn’t hurt to drop the redundant parent directory from the path using

>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
13

The sample code supplementing this article will let you encode, decode, and erase a secret file from the given bitmap with the following commands

>>> (age >= 18) & ~is_self_excluded
0
_8

Ini adalah modul yang dapat dijalankan yang dapat dijalankan dengan memanggil direktori yang melingkupinya. Anda juga dapat membuat arsip format ZIP portabel dari isinya untuk memanfaatkan dukungan aplikasi Python ZIP

Program ini bergantung pada modul dari pustaka standar yang disebutkan dalam artikel dan beberapa lainnya yang mungkin belum pernah Anda dengar sebelumnya. Modul penting adalah

>>> for char in "€uro":
..     print(char, len(char.encode("utf-8")))
...
€ 3
u 1
r 1
o 1
14, yang memaparkan antarmuka Python ke file yang dipetakan memori. Mereka membiarkan Anda memanipulasi file besar menggunakan API file standar dan API urutan. Seolah-olah file tersebut adalah satu daftar besar yang dapat diubah yang dapat Anda potong

Go ahead and play around with the bitmap attached to the supporting materials. It contains a little surprise for you

Kesimpulan

Mastering Python bitwise operators gives you the ultimate freedom to manipulate binary data in your projects. Anda sekarang mengetahui sintaks dan rasa yang berbeda serta tipe data yang mendukungnya. Anda juga dapat menyesuaikan perilaku mereka untuk kebutuhan Anda sendiri

Dalam tutorial ini, Anda belajar caranya

  • Use Python bitwise operators to manipulate individual bits
  • Read and write binary data in a platform-agnostic way
  • Use bitmasks to pack information on a single byte
  • Overload Python bitwise operators in custom data types
  • Hide secret messages in digital images

You also learned how computers use the binary system to represent different kinds of digital information. Anda melihat beberapa cara populer untuk menginterpretasikan bit dan cara mengurangi kurangnya tipe data yang tidak ditandatangani di Python serta cara unik Python untuk menyimpan bilangan bulat di memori

Dengan informasi ini, Anda siap memanfaatkan sepenuhnya data biner dalam kode Anda. Untuk mendownload source code yang digunakan pada contoh watermarking dan melanjutkan percobaan dengan operator bitwise, Anda bisa mengklik link di bawah ini

Dapatkan Kode Sumber. Click here to get the source code you’ll use to learn about Python’s bitwise operators in this tutorial

Mark as Completed

Watch Now This tutorial has a related video course created by the Real Python team. Tonton bersama dengan tutorial tertulis untuk memperdalam pemahaman Anda. Operator Biner, Byte, dan Bitwise dengan Python

🐍 Trik Python 💌

Dapatkan Trik Python singkat & manis yang dikirim ke kotak masuk Anda setiap beberapa hari. Tidak pernah ada spam. Berhenti berlangganan kapan saja. Curated by the Real Python team

Apa itu shift kiri dan shift kanan di python?

Send Me Python Tricks »

Tentang Bartosz Zaczyński

Apa itu shift kiri dan shift kanan di python?
Apa itu shift kiri dan shift kanan di python?

Bartosz adalah instruktur bootcamp, penulis, dan programmer poliglot yang jatuh cinta dengan Python. Dia membantu murid-muridnya masuk ke rekayasa perangkat lunak dengan berbagi lebih dari satu dekade pengalaman komersial di industri TI

» Lebih lanjut tentang Bartosz


Setiap tutorial di Real Python dibuat oleh tim pengembang sehingga memenuhi standar kualitas tinggi kami. Anggota tim yang mengerjakan tutorial ini adalah

Apa itu shift kiri dan shift kanan di python?

Aldren

Apa itu shift kiri dan shift kanan di python?

Daud

Apa itu shift kiri dan shift kanan di python?

Geir Arne

Apa itu shift kiri dan shift kanan di python?

Joanna

Apa itu shift kiri dan shift kanan di python?

Yakub

Master Real-World Python Skills With Unlimited Access to Real Python

Bergabunglah dengan kami dan dapatkan akses ke ribuan tutorial, kursus video langsung, dan komunitas pakar Pythonista

Tingkatkan Keterampilan Python Anda »

Guru Keterampilan Python Dunia Nyata
Dengan Akses Tak Terbatas ke Real Python

Bergabunglah dengan kami dan dapatkan akses ke ribuan tutorial, kursus video langsung, dan komunitas ahli Pythonista

Tingkatkan Keterampilan Python Anda »

Bagaimana menurut anda?

Nilai artikel ini

Tweet Bagikan Bagikan Email

Apa takeaway # 1 Anda atau hal favorit yang Anda pelajari?

Kiat Berkomentar. Komentar yang paling berguna adalah yang ditulis dengan tujuan belajar dari atau membantu siswa lain. dan dapatkan jawaban atas pertanyaan umum di portal dukungan kami

What is left shift and right

The bitwise shift operators are the right-shift operator ( >> ), which moves the bits of an integer or enumeration type expression to the right, and the left-shift operator ( << ), which moves the bits to the left . 1.

Apa yang >> dilakukan dengan Python?

Dengan Python >> disebut operator shift kanan . Ini adalah operator bitwise. Ini membutuhkan representasi objek bitwise sebagai operan pertama. Bit digeser ke kanan dengan jumlah bit yang ditentukan oleh operan kedua.

Apa contoh benar

Operator geser kanan bitwise Python x >> n menggeser representasi biner dari bilangan bulat x dengan posisi n ke kanan. Ini memasukkan bit 0 di sebelah kiri dan menghapus bit paling kanan. Misalnya, jika Anda menggeser kanan representasi biner 0101 dengan satu posisi, Anda akan mendapatkan 0010 .

Bagaimana Anda meninggalkan shift 1 dengan Python?

Contoh. Mari kita ambil nomor 14. Kemudian 14 << 1 akan menggeser posisi barisan biner 1 ke sisi kiri.