リリース・改善中
ビット演算 ガイド · 6/6
この章は現在、英語でのみ提供しています。
Bit manipulation is not just for puzzles. File permissions, network addresses, hash tables, database indexes and game engines all rely on it wherever speed and memory matter. This chapter surveys real uses, lists language-specific pitfalls and points to further reading.
The most common use is packing several on/off options into one integer. Unix permission 755 is nine bits written in octal: rwx for owner, group and others. Python's enum.Flag, C#'s [Flags] enums and Java's EnumSet all use bits underneath.
import stat
from enum import Flag, auto
mode = 0o754 # rwxr-xr--
print(bool(mode & stat.S_IXUSR)) # True: owner may execute
print(bool(mode & stat.S_IWGRP)) # False: group may not write
print(stat.filemode(stat.S_IFREG | mode)) # -rwxr-xr--
class Perm(Flag):
READ = auto()
WRITE = auto()
EXECUTE = auto()
user = Perm.READ | Perm.WRITE
print(Perm.WRITE in user, Perm.EXECUTE in user) # True False
user &= ~Perm.WRITE
print(user) # Perm.READAn IPv4 address is a 32-bit integer; AND it with the subnet mask to get the network address. Routers and firewalls do exactly this for every packet.
import ipaddress
ip = int(ipaddress.IPv4Address("192.168.10.77"))
prefix = 24
mask = (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF
print(ipaddress.IPv4Address(ip & mask)) # 192.168.10.0
print(ipaddress.ip_interface("192.168.10.77/24").network) # 192.168.10.0/24HashMap keeps its capacity a power of two and picks a bucket with (n - 1) & hash, which is cheaper than a modulo.SETBIT, GETBIT and BITCOUNT store huge numbers of booleans, such as daily active users, in little memory.i & -i jumps to the next range.== binds tighter than &, so x & 1 == 0 means . Always parenthesize bitwise expressions.x & (1 == 0)1 << 31 is negative in Java and JavaScript, and 1 << 40 overflows int in C++. Build wide masks with 1L << i (Java), 1ULL << i (C++) or 1n << 40n (JavaScript BigInt).1 << 32 is 1. In C++ it is undefined behavior.>> keeps the sign and >>> fills with zeros. C++ shifts unsigned types logically, and since C++20 right-shifting a negative signed value is defined as arithmetic.bin(-5) is -0b101. To mimic 32-bit results, truncate with & 0xFFFFFFFF.def to_int32(x: int) -> int:
x &= 0xFFFFFFFF
return x - (1 << 32) if x & 0x80000000 else x
print(to_int32(1 << 31)) # -2147483648, like 1 << 31 in Java or JS
print(-1 & 0xFFFFFFFF) # 4294967295, like -1 >>> 0 in JS
print(to_int32(0xDEADBEEF)) # -559038737The XOR swap (a ^= b; b ^= a; a ^= b) is no faster with modern compilers and zeroes the value if both names refer to the same location, so avoid it. Wrap bit tricks in named constants and small functions so readers can follow them.
Bit manipulation powers flags, permissions, network addresses, hash tables and bitmap indexes: anywhere many booleans must be handled quickly and compactly. Mind the differences in precedence, integer width and shift rules between languages, and you can write short, fast code safely.
コメント 0件
ログイン · ログインするとコメントできます。
最初のコメントを書いてみましょう。