Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ MANIFEST
*.DS_Store
.venv
.hypothesis
venv/
33 changes: 33 additions & 0 deletions src/flint/types/qqbar.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from flint.flintlib.types.flint cimport slong
from flint.flintlib.functions.fmpz cimport fmpz_t
from flint.flintlib.functions.fmpq cimport fmpq_t

cdef extern from "flint/qqbar.h" nogil:
ctypedef struct qqbar_struct:
pass
ctypedef qqbar_struct qqbar_t[1]

# Lifecycle methods
void qqbar_init(qqbar_t res)
void qqbar_clear(qqbar_t res)
void qqbar_set(qqbar_t res, const qqbar_t x)
void qqbar_set_si(qqbar_t res, slong x)

# Printing methods
void qqbar_print(const qqbar_t x)
void qqbar_printn(const qqbar_t x, slong n)

# Interoperability setters
void qqbar_set_fmpz(qqbar_t res, const fmpz_t x)
void qqbar_set_fmpq(qqbar_t res, const fmpq_t x)

# Arithmetic operations
void qqbar_add(qqbar_t res, const qqbar_t x, const qqbar_t y)
void qqbar_sub(qqbar_t res, const qqbar_t x, const qqbar_t y)
void qqbar_mul(qqbar_t res, const qqbar_t x, const qqbar_t y)
void qqbar_div(qqbar_t res, const qqbar_t x, const qqbar_t y)

from flint.flint_base.flint_base cimport flint_scalar

cdef class qqbar(flint_scalar):
cdef qqbar_t val
80 changes: 80 additions & 0 deletions src/flint/types/qqbar.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from flint.types.fmpz cimport fmpz
from flint.types.fmpq cimport fmpq

cdef class qqbar(flint_scalar):
"""
The qqbar class represents algebraic numbers.
"""

def __cinit__(self):
qqbar_init(self.val)

def __dealloc__(self):
qqbar_clear(self.val)

def __init__(self, val=None):
if val is not None:
if isinstance(val, qqbar):
qqbar_set(self.val, (<qqbar>val).val)
elif isinstance(val, int):
qqbar_set_si(self.val, val)
elif isinstance(val, fmpz):
qqbar_set_fmpz(self.val, (<fmpz>val).val)
elif isinstance(val, fmpq):
qqbar_set_fmpq(self.val, (<fmpq>val).val)
else:
raise TypeError("Cannot initialize qqbar type from input")

def str(self, Py_ssize_t digits=15):
"""
Converts the algebraic number to a decimal string representation.
"""
import sys
import io

# Temporarily intercept stdout using a clean, cross-platform string buffer
old_stdout = sys.stdout
sys.stdout = io.StringIO()

try:
qqbar_printn(self.val, digits)
sys.stdout.flush()
output = sys.stdout.getvalue()
finally:
sys.stdout = old_stdout

return output.strip()

def __str__(self):
return self.str()

def __repr__(self):
return f"qqbar({self.str()})"

def __add__(x, y):
cdef qqbar res = qqbar()
cdef qqbar c_x = x if isinstance(x, qqbar) else qqbar(x)
cdef qqbar c_y = y if isinstance(y, qqbar) else qqbar(y)
qqbar_add(res.val, c_x.val, c_y.val)
return res

def __sub__(x, y):
cdef qqbar res = qqbar()
cdef qqbar c_x = x if isinstance(x, qqbar) else qqbar(x)
cdef qqbar c_y = y if isinstance(y, qqbar) else qqbar(y)
qqbar_sub(res.val, c_x.val, c_y.val)
return res

def __mul__(x, y):
cdef qqbar res = qqbar()
cdef qqbar c_x = x if isinstance(x, qqbar) else qqbar(x)
cdef qqbar c_y = y if isinstance(y, qqbar) else qqbar(y)
qqbar_mul(res.val, c_x.val, c_y.val)
return res

def __truediv__(x, y):
cdef qqbar res = qqbar()
cdef qqbar c_x = x if isinstance(x, qqbar) else qqbar(x)
cdef qqbar c_y = y if isinstance(y, qqbar) else qqbar(y)
qqbar_div(res.val, c_x.val, c_y.val)
return res