2017-01-15 24 views
5

Python là số nguyên Gaussian - số nguyên Gaussian là số nguyên bình thường hoặc số phức g = a + bi trong đó ab là cả số nguyên và một số chia Gauss của một số nguyên Gaussian g là một số nguyên Gaussian d sao cho g/d cũng là một số nguyên Gaussian.Python 3 - số phức

Tôi có mã sau.

def is_gaussian_integer(c): 
    """ 
     Checks whether a given real or complex number is a Gaussian integer, 
     i.e. a complex number g = a + bi such that a and b are integers. 
    """ 
    if type(c) == int: 
     return True 
    return c.real.is_integer() and c.imag.is_integer() 


def gaussian_divisors(g): 
    """ 
     Generates a sequence of Gaussian divisors of a rational or Gaussian 
     integer g, i.e. a Gaussian integer d such that g/d is also a Gaussian integer. 
    """ 
    if not is_gaussian_integer(g): 
     return 
    if g == 1: 
     yield complex(g, 0) 
     return 
    g = complex(g) if type(g) == int or type(g) == float else g 
    a = b = 1 
    ubound = int(math.sqrt(abs(g))) 
    for a in range(-ubound, ubound + 1): 
     for b in range(-ubound, ubound + 1): 
      if a or b: 
       d = complex(a, b) 
       if is_gaussian_integer(g/d): 
        yield d 
    yield g 

Dường như "hầu hết" hoạt động nhưng đối với một số yếu tố đầu vào, nó thiếu một số ước lượng Gaussian, ví dụ: cho 2 Tôi mong đợi trình tự bao gồm số chia -2 + 0j (chỉ là -2), nhưng nó bị thiếu. Tôi không thể tìm ra lý do tại sao nó đang làm điều này hoặc nơi có khoảng cách trong logic.

In [92]: list(gaussian_divisors(2)) 
Out[92]: [(-1-1j), (-1+0j), (-1+1j), -1j, 1j, (1-1j), (1+0j), (1+1j), (2+0j)] 
+0

Trong python 3 toán tử phân chia số nguyên là '//', không phải '/'. Tôi không có ý tưởng gì với các toán hạng phức tạp. –

+0

Tôi không nghĩ toán tử '//' áp dụng cho các số phức, ví dụ: '1/1j' cho bạn' -1j' như mong đợi nhưng '1 // -1j' ném một lỗi:' TypeError: không thể lấy tầng của số phức .'. Điều này có lẽ vì không có thứ tự tự nhiên của các số phức không giống như số nguyên. – srm

+0

ok, có thể bạn sẽ muốn xác định toán tử chia nhỏ của riêng mình là '/' sẽ không hoạt động chính xác cho các toán hạng đủ lớn. Ngoài ra, đối với 'g = 2',' ubound = 1', do đó vòng lặp của bạn đi từ -1 đến 1. Bạn không bao giờ thử nghiệm -2. –

Trả lời

1

Thay vì chỉ năng suất

yield g 

bạn có thể bổ sung

yield -g 

Bởi vì vòng của bạn bắt đầu và dừng lại ở int(math.sqrt(abs(g))) = int(sqrt(2)) mà chỉ là 1 nên nó sẽ chỉ kiểm tra -1, 01.

Alternativly nếu bạn muốn bao gồm -22 trong vòng của bạn, bạn cần phải hoặc thặng dư ubound hoặc math.ceil các sqrt kết quả.