module FLINT.Utility where
import qualified FLINT.MatrixInteger as FmpzMat
import qualified FLINT.Integer as Fmpz
import qualified FLINT.Type as FLINT
import Text.Printf (printf)
import Control.Exception (bracket_)
import Control.Monad (void)
import Control.Applicative ((<$>))
import Foreign.Marshal.Alloc (allocaBytes)
import Foreign.C.String (peekCString, withCString)
import Foreign.C.Types (CLong)
import Foreign.Ptr (Ptr)
withInteger :: (Ptr FLINT.Integer -> IO a) -> IO a
withInteger act =
allocaBytes FLINT.integerSize $ \ptr ->
bracket_ (Fmpz.init ptr) (Fmpz.clear ptr) (act ptr)
withMatrix :: CLong -> CLong -> (Ptr FLINT.Matrix -> IO a) -> IO a
withMatrix m n act =
allocaBytes FLINT.matrixSize $ \mat ->
bracket_ (FmpzMat.init mat m n) (FmpzMat.clear mat) (act mat)
decimalFromInteger :: Ptr FLINT.Integer -> IO String
decimalFromInteger ptr = do
let base = 10
num_digits <- Fmpz.sizeinbase ptr base
allocaBytes (fromIntegral num_digits + 2) $ \buffer -> do
void $ Fmpz.get_str buffer base ptr
peekCString buffer
naturalPreludeFromFlint :: Ptr FLINT.Integer -> IO Integer
naturalPreludeFromFlint ptr = do
let base = 16
num_digits <- Fmpz.sizeinbase ptr base
allocaBytes (fromIntegral num_digits + 2) $ \buffer -> do
void $ Fmpz.get_str buffer base ptr
read . ("0x"++) <$> peekCString buffer
integerPreludeFromFlint :: Ptr FLINT.Integer -> IO Integer
integerPreludeFromFlint ptr =
withInteger $ \absInt -> do
Fmpz.abs absInt ptr
sgn <- Fmpz.sgn ptr
let base = 16
num_digits <- Fmpz.sizeinbase ptr base
allocaBytes (fromIntegral num_digits + 2) $ \buffer -> do
void $ Fmpz.get_str buffer base absInt
(toInteger sgn *) . read . ("0x"++) <$> peekCString buffer
-- | return sign and turn integer into absolute value
splitSign :: Ptr FLINT.Integer -> IO Ordering
splitSign ptr = do
sgn <- Fmpz.sgn ptr
Fmpz.abs ptr ptr
return $ compare sgn 0
-- | returns success
integerFromDecimal :: Ptr FLINT.Integer -> String -> IO Bool
integerFromDecimal ptr str =
withCString str $ \strPtr ->
(0==) <$> Fmpz.set_str ptr strPtr 10
integerFlintFromPrelude :: Ptr FLINT.Integer -> Integer -> IO ()
integerFlintFromPrelude ptr n =
withCString (printf "%x" n) $ \strPtr ->
void $ Fmpz.set_str ptr strPtr 16