Python math.log2(): Base-2 Logarithms & Binary Computation

The math.log2(x) function computes the base-2 logarithm of a positive real number x (satisfying 2y = x). Introduced in Python 3.3, math.log2(x) provides significantly higher precision than evaluating math.log(x, 2) because it maps directly to hardware C99 log2() instructions rather than computing an intermediate ratio of natural logarithms.

Domain Constraint: Requires strictly positive inputs (x > 0). Passing zero or a negative number raises a ValueError: math domain error.

Syntax & Parameters 🔝

The math.log2() function is part of Python's standard math module:

import math

result = math.log2(x)
Parameter Type Description
x float or int Required. A strictly positive number (> 0.0) whose base-2 logarithm is calculated.
Return Value float The base-2 logarithm of x as a 64-bit IEEE 754 float.
ValueError Exception Raised when x ≤ 0 (e.g. math.log2(0) or negative numbers).
TypeError Exception Raised when passing non-numeric data types (strings, lists, None).

Basic Usage & Exact Powers of Two 🔝

For exact powers of two, math.log2() produces exact integral floating-point numbers:

import math

# Exact positive integer powers of 2
print("log2(1):    ", math.log2(1))       # 2^0 == 1 -> 0.0
print("log2(2):    ", math.log2(2))       # 2^1 == 2 -> 1.0
print("log2(8):    ", math.log2(8))       # 2^3 == 8 -> 3.0
print("log2(1024): ", math.log2(1024))    # 2^10 == 1024 -> 10.0
print("log2(65536):", math.log2(65536))   # 2^16 == 65536 -> 16.0

# Fractional powers of 2 yield negative exponents
print("log2(0.5):  ", math.log2(0.5))     # 2^(-1) == 0.5 -> -1.0
print("log2(0.25): ", math.log2(0.25))    # 2^(-2) == 0.25 -> -2.0
print("log2(0.125):", math.log2(0.125))   # 2^(-3) == 0.125 -> -3.0

# Arbitrary non-power-of-two floats
print("log2(10):   ", round(math.log2(10), 6))  # 3.321928

Output:

log2(1):     0.0
log2(2):     1.0
log2(8):     3.0
log2(1024):  10.0
log2(65536): 16.0
log2(0.5):   -1.0
log2(0.25):  -2.0
log2(0.125): -3.0
log2(10):    3.321928

Precision Advantage: math.log2(x) vs. math.log(x, 2) 🔝

In older Python versions prior to Python 3.3, programmers computed base-2 logs using the two-argument form of math.log(x, 2). Under the hood, math.log(x, 2) calculates:

log(x, 2) = ln(x) / ln(2)

Because ln(2) is an irrational number that cannot be represented exactly in binary floating point, dividing by ln(2) introduces rounding inaccuracies:

import math

powers = [8, 64, 1024, 32768, 1048576]

print(f"{'x':>8} | {'math.log2(x)':>14} | {'math.log(x, 2)':>16} | Difference")
print("-" * 55)

for p in powers:
    res_log2 = math.log2(p)
    res_log_base = math.log(p, 2)
    diff = abs(res_log2 - res_log_base)
    print(f"{p:8d} | {res_log2:14.1f} | {res_log_base:16.14f} | {diff:.2e}")

Output:

       x |   math.log2(x) |   math.log(x, 2) | Difference
-------------------------------------------------------
       8 |            3.0 | 3.00000000000000 | 0.00e+00
      64 |            6.0 | 6.00000000000000 | 0.00e+00
    1024 |           10.0 | 10.0000000000000 | 0.00e+00
   32768 |           15.0 | 14.9999999999999 | 1.78e-15
 1048576 |           20.0 | 20.0000000000000 | 0.00e+00

Notice that for x = 32768, math.log(32768, 2) returns 14.999999999999998, failing strict equality checks (math.log(32768, 2) == 15 is False). In contrast, math.log2(32768) == 15.0 is guaranteed exact.

Domain Error Handling & Non-Finite Values 🔝

Logarithms are undefined for zero and negative real numbers. Passing non-positive arguments raises ValueError: math domain error:

import math

for bad_val in [0.0, -4.0]:
    try:
        math.log2(bad_val)
    except ValueError as err:
        print(f"log2({bad_val}): ValueError -> {err}")

# Special values
print("log2(inf):", math.log2(float('inf')))  # inf
print("log2(nan):", math.log2(float('nan')))  # nan

Output:

log2(0.0): ValueError -> math domain error
log2(-4.0): ValueError -> math domain error
log2(inf): inf
log2(nan): nan

Computer Science: Bit-Length, Binary Search, & Trees 🔝

Base-2 logarithms are ubiquitous across fundamental algorithms and data structures:

1. Minimum Bit-Width for Positive Integers

The minimum number of bits needed to store a positive integer n in binary representation is math.floor(math.log2(n)) + 1, which matches Python's native n.bit_length():

import math

n = 255  # In binary: 0b11111111 (8 bits)
bits_calculated = math.floor(math.log2(n)) + 1
print(f"Bits for {n}: {bits_calculated} == {n.bit_length()}")  # 8 == 8

2. Maximum Comparisons in Binary Search

When performing binary search on a sorted collection of N elements, the maximum number of comparisons required in the worst-case scenario is math.floor(math.log2(N)) + 1:

items_count = 1_000_000  # 1 million sorted records
max_comparisons = math.floor(math.log2(items_count)) + 1
print(f"Max binary search steps for 1M items: {max_comparisons}")  # 20 steps

Hands-on Exercise: Shannon Information Entropy & Password Strength with Assertions 🔝

In cyber-security and information theory, Shannon Entropy measures the unpredictability or information density of a message or password in bits:

H(X) = −∑ P(xi) · log2(P(xi))

Where P(xi) is the frequency probability of character xi in the string. Furthermore, the total password search-space entropy in bits is calculated as E = length × log2(pool_size). Let's build an entropy evaluator verified with self-checking assertions:

Python Exercise: Shannon Entropy & Password Search Space Calculator
import math
from collections import Counter

def shannon_entropy(text):
    """
    Computes Shannon Information Entropy of a string in bits per character.
    H(X) = -sum(p_i * log2(p_i))
    """
    if not text:
        return 0.0
        
    length = len(text)
    counts = Counter(text)
    entropy = 0.0
    
    for count in counts.values():
        prob = count / length
        entropy -= prob * math.log2(prob)
        
    return round(entropy, 4)

def password_search_entropy(password_length, charset_size):
    """Calculates total brute-force entropy in bits: length * log2(charset_size)."""
    if password_length <= 0 or charset_size <= 1:
        raise ValueError("Length must be positive and charset size must be > 1.")
    return round(password_length * math.log2(charset_size), 2)

# Unit Assertions
# A string of identical characters has 0 entropy
assert shannon_entropy("aaaaaa") == 0.0

# Two equally likely characters has exactly 1 bit per character
assert shannon_entropy("ababab") == 1.0

# Four equally likely characters has exactly 2 bits per character
assert shannon_entropy("abcd") == 2.0

# 8-character numeric PIN (charset = 10 digits): 8 * log2(10) = 8 * 3.321928 = 26.58 bits
assert password_search_entropy(8, 10) == 26.58

# 12-character alphanumeric password (charset = 62): 12 * log2(62) = 71.45 bits
assert password_search_entropy(12, 62) == 71.45

print("Shannon Entropy of 'plus2net':       ", shannon_entropy("plus2net"), "bits/char")
print("Search entropy for 16-char password: ", password_search_entropy(16, 94), "bits")
print("All Shannon entropy and password assertions passed successfully!")

Practice in Google Colab & GitHub 🔝

Open in Google Colab View on GitHub

Run all math.log2() examples interactively, benchmark precision against math.log(x, 2), test binary search step limits, and compute password entropy in Google Colab.




Subscribe to our YouTube Channel here



plus2net.com







Python Video Tutorials
Python SQLite Video Tutorials
Python MySQL Video Tutorials
Python Tkinter Video Tutorials
✖
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
© 2000-2026 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer