Chuyển đến nội dung chính

Lũy thừa trong Python: Hướng dẫn toàn diện cho người mới bắt đầu

Nắm vững lũy thừa trong Python bằng nhiều phương pháp, từ hàm dựng sẵn đến các thư viện mạnh như NumPy, và vận dụng chúng trong tình huống thực tế để hiểu sâu hơn.
· 9 phút đọc

Khám phá cùng AI

Phép lũy thừa là nền tảng trong nhiều lĩnh vực lập trình, từ phân tích dữ liệu đến thiết kế thuật toán. Ứng dụng của nó bao gồm phân tích các mẫu tăng trưởng theo hàm mũ trong các bộ dữ liệu lớn như xu hướng mạng xã hội và thực hiện các phép tính toán học như tăng trưởng kép hoặc lãi suất.

Ngoài ra, phép lũy thừa đóng vai trò quan trọng trong Machine Learning (ML) và Trí tuệ nhân tạo (AI), đặc biệt trong mạng nơ-ron và nhận dạng ảnh. Do đó, hiểu cách thực hiện các phép tính với số mũ hiệu quả trong Python là điều thiết yếu.

Trong hướng dẫn này, chúng ta sẽ khám phá nhiều phương pháp để thực hiện phép lũy thừa trong Python. Chúng ta sẽ xem xét các hàm dựng sẵn, hàm từ mô-đun math, và từ thư viện Numpy. Mỗi phương pháp đều có ưu điểm riêng. Để vững kiến thức nền và nâng cao chuyên môn, hãy đăng ký lộ trình kỹ năng Python Programming Fundamentals.

Lũy thừa trong Python

Python cung cấp nhiều cách để tính lũy thừa:

  • **: Toán tử hai dấu hoa thị (**) là lựa chọn đơn giản và cơ bản nhất cho phép lũy thừa. Ví dụ, x ** y tính x mũ y.

  • pow(): Hàm dựng sẵn này nhận hai đối số: cơ số và số mũ. Nó trả về kết quả của việc nâng cơ số lên số mũ. Hàm cũng cho phép đối số thứ ba tùy chọn để tính lũy thừa theo mô-đun. Ví dụ: pow(x, y).

  • math.pow(): Hàm này từ mô-đun math tương tự pow(), nhưng luôn trả về kết quả dạng số thực dấu phẩy động. Nó nhận hai đối số, có thể là float hoặc int. Ví dụ: math.pow(x, y).

  • math.exp(): Một hàm khác từ mô-đun math, trả về hàm mũ tự nhiên của một số, tức là e mũ đối số. Ví dụ: math.exp(argument).

  • np.power(): Hàm này từ thư viện NumPy được thiết kế để làm việc với mảng hoặc ma trận. Nó thực hiện phép lũy thừa theo từng phần tử. Ví dụ: np.power(array, exponent).

Những điều cơ bản về lũy thừa trong Python

Toán tử hai dấu hoa thị (**) là cách trực quan nhất của Python để tính lũy thừa. Toán tử này nâng toán hạng bên trái (cơ số) lên lũy thừa của toán hạng bên phải (số mũ). Nó còn được gọi là toán tử mũ hoặc toán tử lũy thừa.

Nếu bạn muốn cải thiện kỹ năng lập trình Python và học cách code như một lập trình viên thực thụ, hãy xem khóa học Python Programming.

Số mũ dương

Trong đoạn mã này, chúng tôi minh họa cách tính lũy thừa với số mũ dương. Ví dụ, 2 mũ 3 được tính là 2 × 2 × 2, cho kết quả 8. Tương tự, -10 mũ 4 được tính là -10 × -10 × -10 × -10, cho kết quả 10000.

base = 2
exponent = 3
print(base**exponent)  # Output: 8

base = -10
exponent = 4
print(base**exponent)  # Output: 10000

Số mũ âm

Đoạn mã này tính kết quả của việc nâng một cơ số lên số mũ âm. Ví dụ, 5 mũ -2 bằng 0,04. Tương tự, 25 mũ -5 cho kết quả là một giá trị rất nhỏ ở dạng ký hiệu khoa học (1.024e-07).

base = 5
exponent = -2
print(base**exponent) # 0.04

base = 25
exponent = -5
print(base**exponent) # 1.024e-07

Nâng một số lên số mũ âm tương đương với việc lấy nghịch đảo của số đó khi nâng lên số mũ dương.

Nâng một số lên số mũ âm

Trong Python, toán tử ** sẽ trả về ZeroDivisionError nếu bạn nâng 0.0 lên lũy thừa âm vì bất kỳ số nào chia cho 0 đều không xác định.

base = 0
exponent = -5
print(base**exponent)

Kết quả là:

ZeroDivisionError trong Python

Số mũ dạng số thực

Các ví dụ mã cho thấy Python tính đúng kết quả khi nâng một cơ số dương như 2 lên số mũ phân số như 1,5. Tuy nhiên, dùng cơ số âm với số mũ phân số sẽ cho ra một số phức.

base = 2
exponent = 1.5
print(base**exponent) # 2.8284271247461903

base = -0.25
exponent = 1.25
print(base**exponent) # (-0.12500000000000003-0.125j)

Đào sâu hơn: Các hàm dựng sẵn

Python cung cấp nhiều hàm dựng sẵn để tính lũy thừa, nhưng chúng ta sẽ tập trung vào hai hàm: pow() và math.pow(). Thoạt nhìn, các hàm này có vẻ giống nhau, nhưng chúng có một số khác biệt đáng kể.

pow()

Hàm pow() nhận hai đối số bắt buộc: cơ số và số mũ. Tùy chọn, pow() chấp nhận đối số thứ ba để tính phần dư (modulus) của giá trị lũy thừa. Cú pháp như sau: pow(base, exp, mod), trong đó 'mod' là số mô-đun. Hàm này trả về phần dư của phép lũy thừa theo mô-đun.

Lũy thừa cơ bản

Với các phép tính cơ bản, chỉ cần cung cấp cơ số và số mũ cho hàm, cách hoạt động tương tự toán tử **.

r = pow(2, 3)
print(r) # 8

r = pow(4, -10)
print(r) # 2.56e-06

Lũy thừa số thực

Trong đoạn mã dưới đây, chúng ta dùng số thực cho cả cơ số và số mũ, một số trong đó là số âm. Cách tiếp cận này hoạt động tương tự toán tử **.

r = pow(3.5, 2)
print(r)  # 12.25

r = pow(3.5, -2)
print(r)  # 0.08163265306122448

r = pow(3.5, 3.2)
print(r)  # 55.08301986166747

r = pow(-3.5, -3.3)
print(r)  # (-0.009414432347757688+0.012957854474952653j)

r = pow(-3.5, 3.3)
print(r)  # (-36.698070584660925-50.510560868902246j)

Lưu ý: Nếu bạn chỉ cần lũy thừa cơ bản mà không cần tính mô-đun, toán tử ** là giải pháp ngắn gọn và dễ đọc hơn so với hàm pow().

Lũy thừa theo mô-đun

Tham số mô-đun tùy chọn của hàm pow() rất hữu ích khi làm việc với lũy thừa theo mô-đun. Điều này đặc biệt hữu dụng trong mật mã học hoặc khi xử lý các số lớn, vì lũy thừa theo mô-đun mang lại hiệu quả cao hơn. Ví dụ, khi tính 3 mũ 4 theo mô-đun 5, kết quả là 1, vì 81 mô-đun 5 bằng 1.

r = pow(3, 4, 5)
print(r)  # 1

r = pow(123, 456, 789)
print(r)  # 699

r = pow(2, -3, 7)
print(r)  # 1

r = pow(-13, 8, 62)
print(r)  # 7

Bạn có thể thắc mắc vì sao dùng pow() trực tiếp cho lũy thừa mô-đun lại hiệu quả hơn pow(base, exp) % mod hoặc (base**exp) % mod. Hàm dựng sẵn pow() được thiết kế chuyên biệt cho phép toán này, trong khi các phương pháp kia thực hiện những phép tính trung gian không cần thiết. Điều này có thể tạo ra khác biệt đáng kể về hiệu năng, đặc biệt với các giá trị lớn.

import timeit

start_pow_mod = timeit.default_timer()
pow(500000000, 3000, 4000)
stop_pow_mod = timeit.default_timer()

pow_mod_time = stop_pow_mod - start_pow_mod

print("Time using pow(base, exp, mod): ", pow_mod_time)

start_pow_other = timeit.default_timer()
pow(500000000, 3000) % 4000
stop_pow_other = timeit.default_timer()

pow_other_time = stop_pow_other - start_pow_other

print("Time using pow(base, exp) % mod:", pow_other_time)


start_aestrisk = timeit.default_timer()
(500000000**3000) % 4000
stop_aestrisk = timeit.default_timer()

aestrisk_time = stop_aestrisk - start_aestrisk

print("Time using (base ** exp) % mod: ", aestrisk_time)


print(
    f"Speed comparison: pow(base, exp, mod) was {pow_other_time / pow_mod_time} times faster than pow(base, exp) % mod and {aestrisk_time/pow_mod_time} times faster than (base ** exp) % mod"
)

Kết quả là:

lũy thừa theo mô-đun trong Python

Hàm pow() có thể phát sinh các lỗi khác nhau tùy tình huống.

# Cố gắng lấy mô-đun của số phức sẽ phát sinh ValueError.
print(pow(2 + 3j, 4, 5))  # ValueError: complex modulo

# Không được phép truyền đối số thứ ba nếu đối số thứ hai là số âm.
print(pow(10, -11, 4))  # ValueError: base is not invertible for the given modulus

# Nếu đối số thứ nhất hoặc thứ hai là float, đối số thứ ba không được phép.
print(pow(2.4, 3, 4))  # TypeError: pow() 3rd argument not allowed unless all arguments are integers

# Truyền bất kỳ đối số nào là chuỗi sẽ dẫn đến TypeError.
print(pow(2, 4, '3'))  # TypeError: unsupported operand type(s) for pow(): 'int', 'int', 'str'

math.pow()

Hàm math.pow(x, n) nâng x lên lũy thừa n. Hàm math.pow() chuyển các đối số thành số thực và trả về kết quả lũy thừa dưới dạng số thực chính xác. Độ chính xác này trở nên quan trọng trong các lĩnh vực như phân tích dữ liệu và tính toán khoa học, nơi độ chính xác là tối thượng.

Đây là đoạn mã đơn giản. Hàm math.pow() trả về giá trị dấu phẩy động, trong khi hàm pow() trả về giá trị số nguyên.

import math
print(math.pow(6, 3))  # 216.0
print(pow(6, 3))  # 216

Hàm math.pow() không chấp nhận số ảo.

TypeError không thể chuyển complex sang float trong Python

math.pow() không chấp nhận cơ số âm với số mũ phân số vì sẽ phát sinh ValueError.

ValueError math domain error trong Python

Tận dụng thư viện cho lũy thừa nâng cao

Để xử lý các tác vụ lũy thừa nâng cao, như tìm giá trị hàm mũ của một số hoặc tính lũy thừa theo từng phần tử trong mảng hay ma trận, bạn có thể dùng hai hàm: np.power() và math.exp().

np.power()

Trong Python, lũy thừa không chỉ giới hạn ở các hàm dựng sẵn. Python có một thư viện mạnh là NumPy, cho phép thực hiện nhiều phép toán trên mảng. Đôi khi, bạn cần xử lý lũy thừa trên toàn bộ mảng, và đó là lúc np.power() phát huy tác dụng. Nó được thiết kế để lũy thừa theo từng phần tử của mảng.

import numpy as np
r = np.power([2, 4, 8], 2)
print(r)  # [4, 16, 64]

r = np.power([2, 4, 8], [1, 2, 3])
print(r)  # [4 64 4096]

r = np.power([[2, 3, 4], [5, 6, 7]], [1, 2, 3])
print(r) # [[2 9 64] [5 36 343]]

Hàm np.power() không chấp nhận số mũ âm.

import numpy as np
r = np.power([2, 4, 8], -2)
print(r)

Kết quả là:

ValueError khi cố gắng lũy thừa trong Python

Nếu bạn cố gắng nâng một số âm lên số mũ không nguyên, NumPy sẽ trả về giá trị NaN (Not a Number).

image7.png

math.exp()

Hàm math.exp(x) tính giá trị hàm mũ của x, tương đương với việc nâng số Euler e lên lũy thừa x. Số Euler xấp xỉ 2,71828, và trong ký hiệu toán học, phép toán này được viết là e^x.

import math
x = 2
r = math.exp(x)
print("Exponential of", x, ":", r) # 7.38905609893065

Một đặc điểm đáng chú ý của math.exp(x) là tính linh hoạt. Nó có thể xử lý số dương, số âm và cả số thực dấu phẩy động.

import math
print(math.exp(-2))  # 0.1353352832366127
print(math.exp(-2.5))  # 0.0820849986238988
print(math.exp(2.5))  # 12.182493960703473

Ứng dụng thực tiễn và ví dụ

Phép lũy thừa là một phép toán cơ bản trong toán học với vô số ứng dụng trong phân tích dữ liệu và tính toán khoa học.

Nếu bạn muốn nắm vững những điều cơ bản về phân tích dữ liệu với Python, hãy xem khóa học Introduction to Python for Data Science.

Giả sử bạn có một tệp CSV chứa dữ liệu về số tiền gốc, lãi suất và thời gian đầu tư cho nhiều dòng. Bạn có thể tính lãi kép cho mỗi dòng bằng bất kỳ phương pháp nào đã bàn ở trên.

Principal,Rate,Years
1000,0.05,5
2000,0.03,10
1500,0.08,3
3000,0.06,7
2500,0.04,9
1800,0.07,4
2200,0.025,6
3500,0.09,2
2800,0.035,8
4000,0.02,5

Đây là đoạn mã:

import csv


def compound_interest(principal, rate, years):
    return principal * (1 + rate) ** years


# Read data from CSV file

data = []
with open("data.csv", newline="") as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        row["Compound Interest"] = compound_interest(
            float(row["Principal"]), float(row["Rate"]), int(row["Years"])
        )
        data.append(row)
# Write data to a new CSV file with compound interest column

output_file = "data.csv"
fieldnames = ["Principal", "Rate", "Years", "Compound Interest"]

with open(output_file, mode="w", newline="") as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    writer.writeheader()
    for row in data:
        writer.writerow(row)
print("Compound interest calculations saved to", output_file)

Kết quả là:

tính lãi kép trong Python

Tuyệt vời! Bạn đã tính lãi kép cho tất cả các dòng và lưu vào một cột riêng. Bạn có thể dùng dữ liệu này cho các phân tích tiếp theo. Tương tự, có hàng trăm trường hợp sử dụng khác mà phép lũy thừa được dùng rộng rãi, như mô hình hóa tăng trưởng dân số theo thời gian.

Kết luận

Trong hướng dẫn này, chúng ta đã khám phá năm phương pháp khác nhau để tính lũy thừa trong Python, mỗi phương pháp mang lại lợi thế riêng. Bạn có thể dùng chúng cho nhiều kịch bản thực tế, như tính lãi kép, mô hình hóa tăng trưởng dân số, và nhiều hơn nữa.

  • Toán tử hai dấu hoa thị (**): Đơn giản và trực tiếp cho nhu cầu hằng ngày.
  • pow(): Linh hoạt với tùy chọn "modulus" hữu ích.
  • math.pow(): Kết quả chính xác dưới dạng số thực dấu phẩy động.
  • np.power(): Mạnh mẽ cho xử lý mảng với kiểm tra lỗi.
  • math.exp(): Công cụ chuyên dụng để tính giá trị hàm mũ.

Nếu bạn muốn phát triển kỹ năng thống kê và học cách thu thập, phân tích, rút ra kết luận chính xác từ dữ liệu bằng Python, hãy xem khóa học Introduction to Statistics in Python.

Satyam Tripathi

Tác giả

Satyam Tripathi

Câu hỏi thường gặp về lũy thừa trong Python

Khi nào tôi nên dùng math.pow() thay vì toán tử ** trong Python?

Dùng math.pow() khi bạn cần kết quả số thực chính xác cho mục đích khoa học hoặc phân tích dữ liệu. Nếu mục tiêu là sự đơn giản và phép tính không đòi hỏi độ chính xác dấu phẩy động, toán tử ** là đủ.

Python có xử lý được số mũ âm hoặc số mũ phân số không?

Có, Python hỗ trợ số mũ âm và số mũ phân số:

  • Số mũ âm: Dùng toán tử ** hoặc pow() để tính nghịch đảo của một số được nâng lên lũy thừa dương.
  • Số mũ phân số: Dùng toán tử ** hoặc math.pow(). Lưu ý cơ số âm với số mũ phân số sẽ cho ra số phức.
Lũy thừa theo mô-đun được triển khai trong Python như thế nào và vì sao hiệu quả?

Lũy thừa theo mô-đun có thể thực hiện bằng hàm pow() với ba đối số: pow(base, exp, mod). Cách này hiệu quả hơn so với tính (base**exp) % mod vì pow() được tối ưu cho số lớn, giảm các phép tính trung gian.

Vì sao np.power() của NumPy báo lỗi với số mũ âm?

np.power() được thiết kế cho tính toán trên mảng và không hỗ trợ số mũ âm vì chúng hàm ý phép chia, điều này không tương thích với mọi kiểu mảng. Hãy dùng phương pháp thay thế như ** hoặc pow() cho các phép tính như vậy.

Chủ đề

Liên quan