2017-01-15 26 views
5

bir Gauss tamsayının Gauss bölenler bir dizi oluşturmak için bir yöntem yazmak çalışıyorum - a ve b iki tamsayılardır bir Gauss tamsayıdır normal bir tam sayı veya karmaşık sayı g = a + bi dir, ve Bir Gaussian tamsayısının bir Gaussian bölücü olan g bir Gaussian tamsayısıdır d, öyle ki g/d aynı zamanda bir Gaussian tamsayıdır.Python 3 - karmaşık sayılar

Aşağıdaki kodlarım var.

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 

O "çoğunlukla" iş ama bazı girişler için bazı Gauss bölenler, örneğin dışarı eksik görünüyor 2 için dizinin, -2 + 0j (yalnızca -2 olan) bölümünü içermesini beklerdim, ancak eksik. Bunu neden yaptığını ya da mantıkta boşluk olduğunu anlayamıyorum.

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

Piton 3'te tam sayı bölme operatörü '//' değil '/' dır. Karmaşık işlenenlerle ilgili hiçbir fikrim yok. –

+0

"//" operatörünün karmaşık sayılara, örneğin; '1/1j' beklediğiniz gibi -1j' verir, ancak' 1 // -1j' bir hata atar: 'TypeError: karmaşık sayıların zeminini alamazsınız. Bu muhtemelen tamsayılardan farklı olarak karmaşık sayıların doğal bir sıralaması olmadığı için. – srm

+0

tamam, büyük ihtimalle yeterince işlenen için düzgün çalışmaz diye kendi bölünebilirlik operatörünüzü tanımlamak isteyeceksiniz. Ayrıca, g = 2', 'ubound = 1' için, döngüsünüz -1'den 1'e gider. –

cevap

1

yerine sadece

yield g 

Gerekirse ayrıca

yield -g 

senin döngüler başlar ve hangi int(math.sqrt(abs(g))) = int(sqrt(2)) de durdurabilir Çünkü verimli yüzden sadece 1 o olacak sadece deney -1, 0 ve 1.

Eğer ubound veya math.ceilsqrt sonucu artırmak yapmalı ya da döngüler içinde -2 ve 2 eklemek istediğiniz Alternativly eğer.