packages feed

libBF 0.6.8 → 0.6.9

raw patch · 5 files changed

+199/−6 lines, 5 filesdep +math-functionsnew-uploaderPVP ok

version bump matches the API change (PVP)

Dependencies added: math-functions

API changes (from Hackage documentation)

+ LibBF: bfAcos :: BFOpts -> BigFloat -> (BigFloat, Status)
+ LibBF: bfAsin :: BFOpts -> BigFloat -> (BigFloat, Status)
+ LibBF: bfAtan :: BFOpts -> BigFloat -> (BigFloat, Status)
+ LibBF: bfAtan2 :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status)
+ LibBF: bfConstPi :: BFOpts -> (BigFloat, Status)
+ LibBF: bfCos :: BFOpts -> BigFloat -> (BigFloat, Status)
+ LibBF: bfExp :: BFOpts -> BigFloat -> (BigFloat, Status)
+ LibBF: bfLog :: BFOpts -> BigFloat -> (BigFloat, Status)
+ LibBF: bfSin :: BFOpts -> BigFloat -> (BigFloat, Status)
+ LibBF: bfTan :: BFOpts -> BigFloat -> (BigFloat, Status)
+ LibBF.Mutable: facos :: BFOpts -> BF -> BF -> IO Status
+ LibBF.Mutable: fasin :: BFOpts -> BF -> BF -> IO Status
+ LibBF.Mutable: fatan :: BFOpts -> BF -> BF -> IO Status
+ LibBF.Mutable: fatan2 :: BFOpts -> BF -> BF -> BF -> IO Status
+ LibBF.Mutable: fconst_pi :: BFOpts -> BF -> IO Status
+ LibBF.Mutable: fcos :: BFOpts -> BF -> BF -> IO Status
+ LibBF.Mutable: fexp :: BFOpts -> BF -> BF -> IO Status
+ LibBF.Mutable: flog :: BFOpts -> BF -> BF -> IO Status
+ LibBF.Mutable: fsin :: BFOpts -> BF -> BF -> IO Status
+ LibBF.Mutable: ftan :: BFOpts -> BF -> BF -> IO Status

Files

CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for libBF-hs +## 0.6.9 -- 2026-08-26++* Add  `bfConstPi`, `bfExp`, `bfLog`, `bfSin`, `bfCos`, `bfTan`, `bfAsin`,+  `bfAcos`, `bfAtan`, and `bfAtan2`.+ ## 0.6.8 -- 2024.06.05  * Fix a bug that would cause `(>)` and `(>=)` (in the `Ord BigFloat` instance)
libBF.cabal view
@@ -1,7 +1,7 @@ cabal-version:       2.2  name:                libBF-version:             0.6.8+version:             0.6.9 synopsis:            A binding to the libBF library. description:         LibBF is a C library for working with arbitray precision                      IEEE 754 floating point numbers.@@ -12,7 +12,7 @@ maintainer:          iavor.diatchki@gmail.com -- copyright: category:            Data-extra-source-files:  CHANGELOG.md+extra-doc-files:     CHANGELOG.md  source-repository head   type:     git@@ -86,5 +86,6 @@   default-language:   Haskell2010   build-depends:      base,                       libBF,+                      math-functions,                       tasty >= 1.3 && < 1.6,                       tasty-hunit >= 0.10 && < 0.11
src/LibBF.hs view
@@ -44,6 +44,16 @@   , bfFMA, bfMulWord, bfMulInt, bfMul2Exp   , bfSqrt   , bfPow+  , bfConstPi+  , bfExp+  , bfLog+  , bfSin+  , bfCos+  , bfTan+  , bfAsin+  , bfAcos+  , bfAtan+  , bfAtan2      -- * Rounding   , bfRoundFloat, bfRoundInt@@ -303,6 +313,48 @@ -- | Exponentiate a word to a positive integer power. bfPow :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status) bfPow opts (BigFloat x) (BigFloat y) = newBigFloat' (fpow opts x y)++-- | Compute @pi@ using the given options.+bfConstPi :: BFOpts -> (BigFloat,Status)+bfConstPi opt = newBigFloat' (fconst_pi opt)++-- | Compute the exponential function (@exp()@) of a number using the given+-- options.+bfExp :: BFOpts -> BigFloat -> (BigFloat,Status)+bfExp opt (BigFloat x) = newBigFloat' (fexp opt x)++-- | Compute the logarithm (@log()@) of a number using the given options.+bfLog :: BFOpts -> BigFloat -> (BigFloat,Status)+bfLog opt (BigFloat x) = newBigFloat' (flog opt x)++-- | Compute the sine of a number using the given options.+bfSin :: BFOpts -> BigFloat -> (BigFloat,Status)+bfSin opt (BigFloat x) = newBigFloat' (fsin opt x)++-- | Compute the cosine of a number using the given options.+bfCos :: BFOpts -> BigFloat -> (BigFloat,Status)+bfCos opt (BigFloat x) = newBigFloat' (fcos opt x)++-- | Compute the tangent of a number using the given options.+bfTan :: BFOpts -> BigFloat -> (BigFloat,Status)+bfTan opt (BigFloat x) = newBigFloat' (ftan opt x)++-- | Compute the arcsine of a number using the given options.+bfAsin :: BFOpts -> BigFloat -> (BigFloat,Status)+bfAsin opt (BigFloat x) = newBigFloat' (fasin opt x)++-- | Compute the arccosine of a number using the given options.+bfAcos :: BFOpts -> BigFloat -> (BigFloat,Status)+bfAcos opt (BigFloat x) = newBigFloat' (facos opt x)++-- | Compute the arctangent of a number using the given options.+bfAtan :: BFOpts -> BigFloat -> (BigFloat,Status)+bfAtan opt (BigFloat x) = newBigFloat' (fatan opt x)++-- | Compute the two-argument arctangent function of two numbers using the given+-- options.+bfAtan2 :: BFOpts -> BigFloat -> BigFloat -> (BigFloat, Status)+bfAtan2 opts (BigFloat x) (BigFloat y) = newBigFloat' (fatan2 opts x y)  -- | Constant to a 'Double' bfToDouble :: RoundMode -> BigFloat -> (Double, Status)
src/LibBF/Mutable.hsc view
@@ -51,7 +51,16 @@   , fpow   , fround   , frint-+  , fconst_pi+  , fexp+  , flog+  , fsin+  , fcos+  , ftan+  , fasin+  , facos+  , fatan+  , fatan2    -- * Convert from a number   , toDouble@@ -391,8 +400,36 @@ foreign import ccall "bf_sqrt"   bf_sqrt :: Ptr BF -> Ptr BF -> LimbT -> FlagsT -> IO Status +foreign import ccall "bf_const_pi"+  bf_const_pi :: Ptr BF -> LimbT -> FlagsT -> IO Status +foreign import ccall "bf_exp"+  bf_exp :: Ptr BF -> Ptr BF -> LimbT -> FlagsT -> IO Status +foreign import ccall "bf_log"+  bf_log :: Ptr BF -> Ptr BF -> LimbT -> FlagsT -> IO Status++foreign import ccall "bf_sin"+  bf_sin :: Ptr BF -> Ptr BF -> LimbT -> FlagsT -> IO Status++foreign import ccall "bf_cos"+  bf_cos :: Ptr BF -> Ptr BF -> LimbT -> FlagsT -> IO Status++foreign import ccall "bf_tan"+  bf_tan :: Ptr BF -> Ptr BF -> LimbT -> FlagsT -> IO Status++foreign import ccall "bf_asin"+  bf_asin :: Ptr BF -> Ptr BF -> LimbT -> FlagsT -> IO Status++foreign import ccall "bf_acos"+  bf_acos :: Ptr BF -> Ptr BF -> LimbT -> FlagsT -> IO Status++foreign import ccall "bf_atan"+  bf_atan :: Ptr BF -> Ptr BF -> LimbT -> FlagsT -> IO Status++foreign import ccall "bf_atan2"+  bf_atan2 :: Ptr BF -> Ptr BF -> Ptr BF -> LimbT -> FlagsT -> IO Status+ bfArith :: (Ptr BF -> Ptr BF -> Ptr BF -> LimbT -> FlagsT -> IO Status) ->            BFOpts -> BF -> BF -> BF -> IO Status bfArith fun (BFOpts prec flags) (BF fa) (BF fb) (BF fr) =@@ -487,8 +524,51 @@ fpow :: BFOpts -> BF -> BF -> BF -> IO Status fpow (BFOpts prec flags) = bf3 (\out in1 in2 -> bf_pow out in1 in2 prec flags) +-- | Compute @pi@ to the specified precision and store the result in the+-- argument.+fconst_pi :: BFOpts -> BF -> IO Status+fconst_pi (BFOpts p f) (BF fout) = withForeignPtr fout \out -> bf_const_pi out p f +-- | Compute the exponential function (@exp()@) of the first number and store+-- the result in the second.+fexp :: BFOpts -> BF -> BF -> IO Status+fexp (BFOpts p f) = bf2 (\res inp -> bf_exp res inp p f) +-- | Compute the logarithm (@log()@) of the first number and store the result in+-- the second.+flog :: BFOpts -> BF -> BF -> IO Status+flog (BFOpts p f) = bf2 (\res inp -> bf_log res inp p f)++-- | Compute the sine of the first number and store the result in the second.+fsin :: BFOpts -> BF -> BF -> IO Status+fsin (BFOpts p f) = bf2 (\res inp -> bf_sin res inp p f)++-- | Compute the cosine of the first number and store the result in the second.+fcos :: BFOpts -> BF -> BF -> IO Status+fcos (BFOpts p f) = bf2 (\res inp -> bf_cos res inp p f)++-- | Compute the tangent of the first number and store the result in the second.+ftan :: BFOpts -> BF -> BF -> IO Status+ftan (BFOpts p f) = bf2 (\res inp -> bf_tan res inp p f)++-- | Compute the arcsine of the first number and store the result in the second.+fasin :: BFOpts -> BF -> BF -> IO Status+fasin (BFOpts p f) = bf2 (\res inp -> bf_asin res inp p f)++-- | Compute the arccosine of the first number and store the result in the+-- second.+facos :: BFOpts -> BF -> BF -> IO Status+facos (BFOpts p f) = bf2 (\res inp -> bf_acos res inp p f)++-- | Compute the arctangent of the first number and store the result in the+-- second.+fatan :: BFOpts -> BF -> BF -> IO Status+fatan (BFOpts p f) = bf2 (\res inp -> bf_atan res inp p f)++-- | Compute the two-argument arctangent function (@atan2()@) of the first two+-- numbers and store the result in the second.+fatan2 :: BFOpts -> BF -> BF -> BF -> IO Status+fatan2 (BFOpts prec flags) = bf3 (\out in1 in2 -> bf_atan2 out in1 in2 prec flags)   --------------------------------------------------------------------------------
tests/RunUnitTests.hs view
@@ -1,8 +1,10 @@ {-# Language BlockArguments #-}+{-# Language LambdaCase #-} module Main(main) where +import Numeric.MathFunctions.Comparison (within) import Test.Tasty (TestTree, defaultMain, testGroup)-import Test.Tasty.HUnit ((@=?), assertFailure, testCase)+import Test.Tasty.HUnit ((@=?), assertBool, assertEqual, assertFailure, testCase)  import LibBF @@ -46,6 +48,15 @@         , testCase "0 <= NaN" $ False @=? bfPosZero <= bfNaN         ]       ]+    , testGroup "Transcendental functions"+      [ -- LibBF's implementation of atan2 is ever-so-slightly difference from+        -- macOS libc's implementation, so check that their results are within+        -- 1 ULP rather than checking for IEEE equality.+        dblWithin1UlpTestCase "atan2 1 2" atan2 (bfAtan2 (float64 NearEven)) 1 2+      , dblWithin1UlpTestCase "atan2 2 1" atan2 (bfAtan2 (float64 NearEven)) 2 1+      , checkPredicateTestCase "sin" (bfSin (float256 NearEven)) (bfIsZero) (bfFromDouble 0)+      , checkPredicateTestCase "exp" (bfExp (float256 NearEven)) (== (bfFromDouble 1)) (bfFromDouble 0)+      ]     ]  statusUnderflow :: Status -> Bool@@ -63,11 +74,35 @@   (Double -> Double -> Double) ->   (BigFloat -> BigFloat -> (BigFloat, Status)) ->   Double -> Double -> TestTree-dblTestCase op opD opBF x y =+dblTestCase = dblCompareTestCase (@=?)++-- Check that a binary operation over BigFloats returns approximately the same+-- result as the corresponding operation over doubles. Here, "approximately"+-- means "within 1 unit in the last place (ULP)". This is a very crude way to+-- check if two values are approximately equal, so use this with caution.+dblWithin1UlpTestCase ::+  String ->+  (Double -> Double -> Double) ->+  (BigFloat -> BigFloat -> (BigFloat, Status)) ->+  Double -> Double -> TestTree+dblWithin1UlpTestCase = dblCompareTestCase $ \expected actual ->+  assertBool "Values not within 1 ULP" $ within 1 expected actual++-- Construct a test case that compares the result of a binary BigFloat+-- operation against the same result as the corresponding operation over+-- doubles.+dblCompareTestCase ::+  -- How to compare the expected result against the actual result.+  (Double -> Double -> IO ()) ->+  String ->+  (Double -> Double -> Double) ->+  (BigFloat -> BigFloat -> (BigFloat, Status)) ->+  Double -> Double -> TestTree+dblCompareTestCase resCmp op opD opBF x y =   testCase (unwords [show x, op, show y]) $   case z1 of     Left err -> assertFailure ("status: " ++ err)-    Right actual -> expected @=? actual+    Right actual -> resCmp expected actual   where   expected = opD x y   z1 = case opBF (bfFromDouble x) (bfFromDouble y) of@@ -82,3 +117,23 @@ bfSubnormalTestCase bf expected =   testCase (show bf) $   expected @=? bfIsSubnormal (float32 NearEven) bf++checkPredicateTestCase ::+  Show a =>+  String ->+  (a -> (BigFloat, Status)) ->+  (BigFloat -> Bool) ->+  a ->+  TestTree+checkPredicateTestCase opName opBF predicate input =+  testCase opName $ do+    assertEqual+      ("Status '" ++ show bfStatus ++ "' not OK for " ++ describeOp)+      bfStatus+      Ok+    assertBool+      ("Test predicate failed on result " ++ show bfRes ++ " on " ++ describeOp)+      (predicate bfRes)+  where+    (bfRes, bfStatus) = opBF input+    describeOp = opName ++ "(" ++ show input ++ ")"