packages feed

fp-ieee 0.1.0.1 → 0.1.0.2

raw patch · 9 files changed

+110/−422 lines, 9 filesdep +tasty-benchdep −decimal-arithmeticdep −gaugedep ~ghc-bignumPVP ok

version bump matches the API change (PVP)

Dependencies added: tasty-bench

Dependencies removed: decimal-arithmetic, gauge

Dependency ranges changed: ghc-bignum

API changes (from Hackage documentation)

Files

ChangeLog.md view
@@ -1,5 +1,10 @@ # Changelog for fp-ieee +## Version 0.1.0.2 (2021-11-30)++* Allow ghc-bignum 1.2.+* Documentation changes.+ ## Version 0.1.0.1 (2021-01-02)  Fix some packaging issues.
− decimal-test/NextFloatSpec.hs
@@ -1,42 +0,0 @@-module NextFloatSpec where-import           Data.Proxy-import           Numeric.Decimal-import           Numeric.Floating.IEEE-import           Test.Hspec-import           Test.Hspec.QuickCheck (prop)-import           Test.QuickCheck-import           Util (forAllFloats, sameFloatP)--isPositiveZero :: RealFloat a => a -> Bool-isPositiveZero x = x == 0 && not (isNegativeZero x)--prop_nextUp_nextDown :: (RealFloat a, Show a) => Proxy a -> a -> Property-prop_nextUp_nextDown _ x = x /= (-1/0) ==>-  let x' = nextUp (nextDown x)-  in x' `sameFloatP` x .||. (isPositiveZero x .&&. isNegativeZero x')--prop_nextDown_nextUp :: (RealFloat a, Show a) => Proxy a -> a -> Property-prop_nextDown_nextUp _ x = x /= (1/0) ==>-  let x' = nextDown (nextUp x)-  in x' `sameFloatP` x .||. (isNegativeZero x .&&. isPositiveZero x')--{-# NOINLINE spec #-}-spec :: Spec-spec = do-  describe "Decimal32" $ do-    let proxy :: Proxy Decimal32-        proxy = Proxy-    prop "nextUp . nextDown == id (unless -inf)" $ forAllFloats $ prop_nextUp_nextDown proxy-    prop "nextDown . nextUp == id (unless inf)" $ forAllFloats $ prop_nextDown_nextUp proxy--  describe "Decimal64" $ do-    let proxy :: Proxy Decimal64-        proxy = Proxy-    prop "nextUp . nextDown == id (unless -inf)" $ forAllFloats $ prop_nextUp_nextDown proxy-    prop "nextDown . nextUp == id (unless inf)" $ forAllFloats $ prop_nextDown_nextUp proxy--  describe "Decimal128" $ do-    let proxy :: Proxy Decimal128-        proxy = Proxy-    prop "nextUp . nextDown == id (unless -inf)" $ forAllFloats $ prop_nextUp_nextDown proxy-    prop "nextDown . nextUp == id (unless inf)" $ forAllFloats $ prop_nextDown_nextUp proxy
− decimal-test/Spec.hs
@@ -1,27 +0,0 @@-{-# LANGUAGE NumericUnderscores #-}-import qualified NextFloatSpec-import           Numeric.Decimal-import           Numeric.Floating.IEEE-import           Test.Hspec-import           Test.Hspec.Core.Spec--allowFailure :: String -> Item a -> Item a-allowFailure message item@(Item { itemExample = origExample }) = item { itemExample = newExample }-  where-    newExample params around callback = do-      result <- origExample params around callback-      case result of-        Result { resultStatus = Failure loc reason } -> do-          let message' = case reason of-                           NoReason -> message-                           _ -> message ++ ": " ++ show reason-          return result { resultStatus = Pending loc (Just message') }-        _ -> return result--main :: IO ()-main = hspec $ do-  mapSpecItem_ (allowFailure "decimal-arithmetic's floatRange may be incorrect") $ do-    it "maxFinite :: Decimal32" $ (maxFinite :: Decimal32) == 9.999_999e96 -- 7 digits-    it "maxFinite :: Decimal64" $ (maxFinite :: Decimal64) == 9.999_999_999_999_999e384 -- 16 digits-    it "maxFinite :: Decimal128" $ (maxFinite :: Decimal128) == 9.999_999_999_999_999_999_999_999_999_999_999e6144 -- 34 digits-  describe "NextFloat" NextFloatSpec.spec
− decimal-test/Util.hs
@@ -1,71 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# OPTIONS_GHC -Wno-orphans #-}-module Util where-import           Control.Applicative-import           Data.Ratio-import           Numeric-import           Numeric.Decimal-import           Numeric.Floating.IEEE-import           System.Random-import           Test.QuickCheck---- | Compares two floating point values.------ Unlike @(==)@, @+0@ and @-0@ are considered distinct and NaNs are equal.------ >>> sameFloat 0 (-0 :: Double)--- False--- >>> sameFloat (0/0) (0/0 :: Double)--- True-sameFloat :: RealFloat a => a -> a -> Bool-sameFloat x y | isNaN x && isNaN y = True-              | x == 0 && y == 0 = isNegativeZero x == isNegativeZero y-              | otherwise = x == y--sameFloatP :: (RealFloat a, Show a) => a -> a -> Property-sameFloatP x y = counterexample (shows x . showString (interpret res) . showHFloat y $ "") res-  where-    res = sameFloat x y-    interpret True  = " === "-    interpret False = " =/= "--infix 4 `sameFloat`, `sameFloatP`--variousFloats :: forall a. (RealFloat a, Arbitrary a, Random a, Show a) => Gen a-variousFloats = frequency-  [ (10, arbitrary)-  , (10, choose (-1, 1))-  , (10, (* encodeFloat 1 expMin) <$> choose (-1, 1) ) -- subnormal or very small normal-  , (10, (* encodeFloat 1 (expMax-1)) <$> choose (-2, 2) ) -- infinity or very large normal-  , (1, pure 0) -- positive zero-  , (1, pure (-0)) -- negative zero-  , (1, pure (1/0)) -- positive infinity-  , (1, pure (-1/0)) -- negative infinity-  , (1, pure (0/0)) -- NaN-  , (1, pure maxFinite) -- max finite-  , (1, pure (-maxFinite)) -- min negative-  , (1, pure minPositive) -- min positive-  , (1, pure (-minPositive)) -- max negative-  ]-  where (expMin,expMax) = floatRange (undefined :: a)--forAllFloats :: (RealFloat a, Arbitrary a, Random a, Show a, Testable prop) => (a -> prop) -> Property-forAllFloats = forAllShow variousFloats (\x -> show x)--forAllFloats2 :: (RealFloat a, Arbitrary a, Random a, Show a, Testable prop) => (a -> a -> prop) -> Property-forAllFloats2 f = forAllFloats $ \x -> forAllFloats $ \y -> f x y--forAllFloats3 :: (RealFloat a, Arbitrary a, Random a, Show a, Testable prop) => (a -> a -> a -> prop) -> Property-forAllFloats3 f = forAllFloats $ \x -> forAllFloats $ \y -> forAllFloats $ \z -> f x y z---- orphan instances-instance (FinitePrecision p, Rounding r) => Arbitrary (Decimal p r) where-  arbitrary = arbitrarySizedFractional-  shrink = shrinkDecimal--instance (FinitePrecision p, Rounding r) => Random (Decimal p r) where-  randomR (lo,hi) g = let (x,g') = random g-                      in (lo + x * (hi - lo), g') -- TODO: avoid overflow-  random g = let x :: Int-                 (x,g') = random g-             in (fromRational (toInteger x % 1000), g') -- TODO
fp-ieee.cabal view
@@ -1,13 +1,7 @@-cabal-version: 1.12---- This file has been generated from package.yaml by hpack version 0.33.0.------ see: https://github.com/sol/hpack------ hash: 62a346063dd10a9b7bb7de4d7624dd805ceef339ead48206730d6c47e94e17d2+cabal-version: 2.2  name:           fp-ieee-version:        0.1.0.1+version:        0.1.0.2 synopsis:       IEEE 754-2019 compliant operations description:    Please see the README on GitHub at <https://github.com/minoki/haskell-floating-point/tree/master/fp-ieee#readme> category:       Numeric, Math@@ -16,7 +10,7 @@ author:         ARATA Mizuki maintainer:     minorinoki@gmail.com copyright:      2020-2021 ARATA Mizuki-license:        BSD3+license:        BSD-3-Clause license-file:   LICENSE build-type:     Simple extra-source-files:@@ -26,14 +20,15 @@ source-repository head   type: git   location: https://github.com/minoki/haskell-floating-point+  subdir: fp-ieee -flag f16c-  description: Use F16C instructions on x86+flag pure-hs+  description: Disable FFI   manual: True   default: False -flag float128-  description: Support Float128 via float128 package+flag sse4_1+  description: Use SSE4.1 instructions on x86   manual: True   default: False @@ -42,32 +37,69 @@   manual: True   default: False -flag ghc-bignum-  description: Use ghc-bignum package-  manual: False-  default: True+flag f16c+  description: Use F16C instructions on x86+  manual: True+  default: False +-- flag x87-long-double+--   description: Support x87 "long double" via long-double package+--   manual: True+--   default: False++flag float128+  description: Support Float128 via float128 package+  manual: True+  default: False+ flag half   description: Support Half (float16) via half package   manual: True   default: False  flag integer-gmp-  description: Use integer-gmp package+  description: Use integer-gmp package on GHC 8.x   manual: False   default: True -flag pure-hs-  description: Disable FFI-  manual: True-  default: False+flag ghc-bignum+  description: Use ghc-bignum package on GHC 9.x+  manual: False+  default: True -flag sse4_1-  description: Use SSE4.1 instructions on x86-  manual: True-  default: False+common deps+  build-depends:+      -- We use a post-GHC 8.6 language extension: NumericUnderscores+      -- cast{Word32,Word64}To{Float,Double}, cast{Float,Double}To{Word32,Word64} are since base-4.10.0.0 (GHC 8.2)+      -- Semigroup((<>)) is exported from Prelude since base-4.11.0.0 (GHC 8.4)+      base >=4.12 && <5+  if !flag(pure-hs)+    cpp-options: -DUSE_FFI+  if flag(float128)+    -- Support Float128+    cpp-options: -DUSE_FLOAT128+    build-depends:+        float128 ==0.1.*+  if flag(half)+    -- Support Half+    -- Note that half-0.3's isInfinite is buggy (https://github.com/ekmett/half/issues/23)+    cpp-options: -DUSE_HALF+    build-depends:+        half ==0.3.*+  -- if flag(x87-long-double)+  --   cpp-options: -DUSE_X87_LONG_DOUBLE+  --   build-depends:+  --       long-double ==??? +common options+  ghc-options: -Wcompat+  if arch(i386)+    -- Always enable SSE2 on i386+    ghc-options: -msse2+    cc-options: -msse2 -mfpmath=sse+ library+  import: deps, options   exposed-modules:       Numeric.Floating.IEEE       Numeric.Floating.IEEE.Internal@@ -94,60 +126,9 @@       Numeric.Floating.IEEE.Internal.Rounding.Rational   hs-source-dirs:       src-  ghc-options: -Wall   build-depends:-      base >=4.12 && <5-    , integer-logarithms >=1 && <1.1-  if arch(i386)-    ghc-options: -msse2-    cc-options: -msse2 -mfpmath=sse-  if !flag(pure-hs)-    cpp-options: -DUSE_FFI-  if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && flag(sse4_1)-    cpp-options: -DHAS_FAST_ROUNDEVEN-    cc-options: -msse4.1-    c-sources:-        cbits/roundeven.c-  if !flag(pure-hs) && arch(aarch64)-    cpp-options: -DHAS_FAST_ROUNDEVEN-    c-sources:-        cbits/roundeven.c-  if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && flag(fma3)-    cpp-options: -DHAS_FAST_FMA-    cc-options: -mfma-    c-sources:-        cbits/fma.c-  if !flag(pure-hs) && arch(aarch64)-    cpp-options: -DHAS_FAST_FMA-    c-sources:-        cbits/fma.c-  if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && !os(windows)-    cpp-options: -DUSE_C99_FMA-  if !flag(pure-hs) && arch(aarch64)-    cpp-options: -DHAS_FAST_MINMAX-    c-sources:-        cbits/minmax.c-  if flag(float128)-    cpp-options: -DUSE_FLOAT128-    build-depends:-        float128 >=0.1 && <0.2-  if flag(half)-    cpp-options: -DUSE_HALF-    build-depends:-        half >=0.3 && <0.4-  if !flag(pure-hs) && flag(half) && arch(x86_64) && flag(f16c)-    cpp-options: -DHAS_FAST_HALF_CONVERSION-    cc-options: -mf16c-    c-sources:-        cbits/half.c-  if !flag(pure-hs) && flag(half) && arch(aarch64)-    cpp-options: -DHAS_FAST_HALF_CONVERSION-    c-sources:-        cbits/half.c-  if !flag(pure-hs) && (arch(aarch64) || arch(x86_64))-    cpp-options: -DHAS_FAST_CANONICALIZE-    c-sources:-        cbits/canonicalize.c+      integer-logarithms >=1 && <1.1+  ghc-options: -Wall   if flag(half)     other-modules:         Numeric.Floating.IEEE.Internal.Half@@ -156,66 +137,42 @@         Numeric.Floating.IEEE.Internal.Float128   if flag(integer-gmp) && impl(ghc < 9.0.0)     build-depends:-        integer-gmp >=1.0 && <1.1+        -- integer-gmp-1.1 is based on ghc-bignum, which is not what we want+        integer-gmp ==1.0.*   if flag(ghc-bignum) && impl(ghc >= 9.0.0)     build-depends:-        ghc-bignum >=1.0 && <1.1-  default-language: Haskell2010--test-suite fp-ieee-decimal-test-  type: exitcode-stdio-1.0-  main-is: Spec.hs-  other-modules:-      NextFloatSpec-      Util-  hs-source-dirs:-      decimal-test-  ghc-options: -threaded -rtsopts -with-rtsopts=-N -fno-ignore-asserts-  build-depends:-      QuickCheck-    , base >=4.12 && <5-    , decimal-arithmetic-    , fp-ieee-    , hspec-    , hspec-core-    , random-  if arch(i386)-    ghc-options: -msse2-    cc-options: -msse2 -mfpmath=sse-  if !flag(pure-hs)-    cpp-options: -DUSE_FFI+        ghc-bignum >=1.0 && <1.3+  -- Fast roundeven: needs SSE4.1 on x86   if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && flag(sse4_1)     cpp-options: -DHAS_FAST_ROUNDEVEN     cc-options: -msse4.1     c-sources:         cbits/roundeven.c+  -- Fast roundeven: always available on AArch64   if !flag(pure-hs) && arch(aarch64)     cpp-options: -DHAS_FAST_ROUNDEVEN     c-sources:         cbits/roundeven.c+  -- Fast FMA: needs FMA3 on x86 (FMA4 is not supported by this package)   if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && flag(fma3)     cpp-options: -DHAS_FAST_FMA     cc-options: -mfma     c-sources:         cbits/fma.c+  -- Fast FMA: always available on AArch64   if !flag(pure-hs) && arch(aarch64)     cpp-options: -DHAS_FAST_FMA     c-sources:         cbits/fma.c+  -- Enable use of libm's fma unless "pure-hs" is set; but not on Windows+  -- (mingw-w64's fma is not reliable)   if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && !os(windows)     cpp-options: -DUSE_C99_FMA+  -- Fast min/max: available on AArch64   if !flag(pure-hs) && arch(aarch64)     cpp-options: -DHAS_FAST_MINMAX     c-sources:         cbits/minmax.c-  if flag(float128)-    cpp-options: -DUSE_FLOAT128-    build-depends:-        float128 >=0.1 && <0.2-  if flag(half)-    cpp-options: -DUSE_HALF-    build-depends:-        half >=0.3 && <0.4   if !flag(pure-hs) && flag(half) && arch(x86_64) && flag(f16c)     cpp-options: -DHAS_FAST_HALF_CONVERSION     cc-options: -mf16c@@ -232,66 +189,16 @@   default-language: Haskell2010  test-suite fp-ieee-doctests+  import: deps, options   type: exitcode-stdio-1.0   main-is: doctests.hs-  other-modules:-      Paths_fp_ieee   build-depends:-      base >=4.12 && <5-    , doctest >=0.8-  if arch(i386)-    ghc-options: -msse2-    cc-options: -msse2 -mfpmath=sse-  if !flag(pure-hs)-    cpp-options: -DUSE_FFI-  if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && flag(sse4_1)-    cpp-options: -DHAS_FAST_ROUNDEVEN-    cc-options: -msse4.1-    c-sources:-        cbits/roundeven.c-  if !flag(pure-hs) && arch(aarch64)-    cpp-options: -DHAS_FAST_ROUNDEVEN-    c-sources:-        cbits/roundeven.c-  if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && flag(fma3)-    cpp-options: -DHAS_FAST_FMA-    cc-options: -mfma-    c-sources:-        cbits/fma.c-  if !flag(pure-hs) && arch(aarch64)-    cpp-options: -DHAS_FAST_FMA-    c-sources:-        cbits/fma.c-  if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && !os(windows)-    cpp-options: -DUSE_C99_FMA-  if !flag(pure-hs) && arch(aarch64)-    cpp-options: -DHAS_FAST_MINMAX-    c-sources:-        cbits/minmax.c-  if flag(float128)-    cpp-options: -DUSE_FLOAT128-    build-depends:-        float128 >=0.1 && <0.2-  if flag(half)-    cpp-options: -DUSE_HALF-    build-depends:-        half >=0.3 && <0.4-  if !flag(pure-hs) && flag(half) && arch(x86_64) && flag(f16c)-    cpp-options: -DHAS_FAST_HALF_CONVERSION-    cc-options: -mf16c-    c-sources:-        cbits/half.c-  if !flag(pure-hs) && flag(half) && arch(aarch64)-    cpp-options: -DHAS_FAST_HALF_CONVERSION-    c-sources:-        cbits/half.c-  if !flag(pure-hs) && (arch(aarch64) || arch(x86_64))-    cpp-options: -DHAS_FAST_CANONICALIZE-    c-sources:-        cbits/canonicalize.c+      doctest >=0.8+    , QuickCheck   default-language: Haskell2010  test-suite fp-ieee-test+  import: deps, options   type: exitcode-stdio-1.0   main-is: Spec.hs   other-modules:@@ -311,63 +218,12 @@   ghc-options: -threaded -rtsopts -with-rtsopts=-N -fno-ignore-asserts   build-depends:       QuickCheck-    , base >=4.12 && <5     , fp-ieee     , hspec     , hspec-core     , integer-logarithms     , random-  if arch(i386)-    ghc-options: -msse2-    cc-options: -msse2 -mfpmath=sse-  if !flag(pure-hs)-    cpp-options: -DUSE_FFI-  if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && flag(sse4_1)-    cpp-options: -DHAS_FAST_ROUNDEVEN-    cc-options: -msse4.1-    c-sources:-        cbits/roundeven.c-  if !flag(pure-hs) && arch(aarch64)-    cpp-options: -DHAS_FAST_ROUNDEVEN-    c-sources:-        cbits/roundeven.c-  if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && flag(fma3)-    cpp-options: -DHAS_FAST_FMA-    cc-options: -mfma-    c-sources:-        cbits/fma.c-  if !flag(pure-hs) && arch(aarch64)-    cpp-options: -DHAS_FAST_FMA-    c-sources:-        cbits/fma.c-  if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && !os(windows)-    cpp-options: -DUSE_C99_FMA-  if !flag(pure-hs) && arch(aarch64)-    cpp-options: -DHAS_FAST_MINMAX-    c-sources:-        cbits/minmax.c-  if flag(float128)-    cpp-options: -DUSE_FLOAT128-    build-depends:-        float128 >=0.1 && <0.2   if flag(half)-    cpp-options: -DUSE_HALF-    build-depends:-        half >=0.3 && <0.4-  if !flag(pure-hs) && flag(half) && arch(x86_64) && flag(f16c)-    cpp-options: -DHAS_FAST_HALF_CONVERSION-    cc-options: -mf16c-    c-sources:-        cbits/half.c-  if !flag(pure-hs) && flag(half) && arch(aarch64)-    cpp-options: -DHAS_FAST_HALF_CONVERSION-    c-sources:-        cbits/half.c-  if !flag(pure-hs) && (arch(aarch64) || arch(x86_64))-    cpp-options: -DHAS_FAST_CANONICALIZE-    c-sources:-        cbits/canonicalize.c-  if flag(half)     other-modules:         HalfSpec   if flag(float128)@@ -376,64 +232,14 @@   default-language: Haskell2010  benchmark fp-ieee-benchmark+  import: deps, options   type: exitcode-stdio-1.0   main-is: Benchmark.hs-  other-modules:-      Paths_fp_ieee   hs-source-dirs:       benchmark   build-depends:-      base >=4.12 && <5-    , fp-ieee-    , gauge-  if arch(i386)-    ghc-options: -msse2-    cc-options: -msse2 -mfpmath=sse-  if !flag(pure-hs)-    cpp-options: -DUSE_FFI-  if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && flag(sse4_1)-    cpp-options: -DHAS_FAST_ROUNDEVEN-    cc-options: -msse4.1-    c-sources:-        cbits/roundeven.c-  if !flag(pure-hs) && arch(aarch64)-    cpp-options: -DHAS_FAST_ROUNDEVEN-    c-sources:-        cbits/roundeven.c-  if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && flag(fma3)-    cpp-options: -DHAS_FAST_FMA-    cc-options: -mfma-    c-sources:-        cbits/fma.c-  if !flag(pure-hs) && arch(aarch64)-    cpp-options: -DHAS_FAST_FMA-    c-sources:-        cbits/fma.c-  if !flag(pure-hs) && (arch(i386) || arch(x86_64)) && !os(windows)-    cpp-options: -DUSE_C99_FMA-  if !flag(pure-hs) && arch(aarch64)-    cpp-options: -DHAS_FAST_MINMAX-    c-sources:-        cbits/minmax.c-  if flag(float128)-    cpp-options: -DUSE_FLOAT128-    build-depends:-        float128 >=0.1 && <0.2-  if flag(half)-    cpp-options: -DUSE_HALF-    build-depends:-        half >=0.3 && <0.4-  if !flag(pure-hs) && flag(half) && arch(x86_64) && flag(f16c)-    cpp-options: -DHAS_FAST_HALF_CONVERSION-    cc-options: -mf16c-    c-sources:-        cbits/half.c-  if !flag(pure-hs) && flag(half) && arch(aarch64)-    cpp-options: -DHAS_FAST_HALF_CONVERSION-    c-sources:-        cbits/half.c-  if !flag(pure-hs) && (arch(aarch64) || arch(x86_64))-    cpp-options: -DHAS_FAST_CANONICALIZE-    c-sources:-        cbits/canonicalize.c+      fp-ieee+    , tasty-bench+  mixins:+      tasty-bench (Test.Tasty.Bench as Gauge, Test.Tasty.Bench as Gauge.Main)   default-language: Haskell2010
src/Numeric/Floating/IEEE.hs view
@@ -117,7 +117,8 @@   -- ** 5.5.1 Sign bit operations   --   -- |-  -- For IEEE-compliant floating-point types, 'negate' and 'abs' from "Prelude" should comply with IEEE semantics.+  -- For IEEE-compliant floating-point types, 'negate' from "Prelude" should comply with IEEE semantics.+  -- 'abs' should also comply with IEEE semantics, but unfortunately it does not handle the sign bit of NaN on via-C backend and SPARC NCG backend.   , negate   , abs   -- |@@ -208,9 +209,10 @@ -- == 'Num' -- --     * '(+)', '(-)', and '(*)' should be correctly-rounding.---     * 'negate', 'abs' should comply with IEEE semantics.---     * 'fromInteger' should be correctly-rounding, but unfortunately not for 'Float' and 'Double' (see GHC's [#17231](https://gitlab.haskell.org/ghc/ghc/-/issues/17231)).---       This module provides a correctly-rounding alternative: 'fromIntegerTiesToEven'.+--     * 'negate' should comply with IEEE semantics.+--     * 'abs' should comply with IEEE semantics, but unfortunately it does not handle the sign bit of NaN for 'Float' and 'Double' on via-C backend and SPARC NCG backend.+--     * 'fromInteger' should be correctly-rounding, but unfortunately not for 'Float' and 'Double' on GHC <= 9.0 (see GHC's [#17231](https://gitlab.haskell.org/ghc/ghc/-/issues/17231)).+--       This module provides an always-correctly-rounding alternative: 'fromIntegerTiesToEven'. -- -- == 'Fractional' --@@ -242,9 +244,17 @@ --     * 'encodeFloat' should accept the significand in the range @[0, floatRadix x ^ floatDigits x]@. This library does not assume a particular rounding behavior when the result cannot be expressed in the target type. --     * @'exponent' x@: The exponent offset by 1: \(\mathrm{logB}(x)+1\). Returns an integer in \([\mathit{emin}+1,\mathit{emax}+1]\) if @x@ is normal, or in \([\mathit{emin}-p+2,\mathit{emin}]\) if @x@ is subnormal. --     * @'significand' x@: Returns the significand of @x@ as a value between \([1/b,1)\).---     * 'scaleFloat': This library does not assume a particular rounding behavior when the result is subnormal.+--     * 'scaleFloat': Rounding may occur when the result is subnormal. This library does not assume a particular rounding behavior when the result is subnormal. --     * 'isNaN' --     * 'isInfinite' --     * 'isDenormalized' --     * 'isNegativeZero' --     * 'isIEEE' should return @True@ if you are using the type with this library.+--+-- == Other functions+--+-- Here is a list of known issues with other floating-point functions on GHC 8.6 or later:+--+--     * @('^^')@ may cause undue underflow when constructing very small value like @2^^(-1074)@ (see [GHC's #4413](https://gitlab.haskell.org/ghc/ghc/-/issues/4413)).+--     * 'realToFrac' may behave differently depending on optimization flags (see [GHC's #3676](https://gitlab.haskell.org/ghc/ghc/-/issues/3676)). Don't use 'realToFrac' on values that potentially contain signed zeroes, infinities or NaN, or use 'realFloatToFrac' instead.+--     * On GHC <= 8.8, 'GHC.Float.castFloatToWord32' may produce exotic 'Word32' value on 64-bit systems (see [GHC's #16617](https://gitlab.haskell.org/ghc/ghc/-/issues/16617)).
src/Numeric/Floating/IEEE/Internal/Classify.hs view
@@ -61,12 +61,14 @@ -- | -- Comparison with IEEE 754 @totalOrder@ predicate. --+-- Floating-point numbers are ordered as,+-- \(-\infty < \text{negative reals} < -0 < +0 < \text{positive reals} < +\infty < \mathrm{NaN}\).+-- -- Since 'RealFloat' constraint is insufficient to query the sign and payload of NaNs, -- this function treats all NaNs as positive and does not make distinction between them. -- See also "Numeric.Floating.IEEE.NaN". ----- Floating-point numbers are ordered as,--- \(-\infty < \text{negative reals} < -0 < +0 < \text{positive reals} < +\infty < \mathrm{NaN}\).+-- Also, for the same reason, this function cannot distinguish the members of a cohort. compareByTotalOrder :: RealFloat a => a -> a -> Ordering compareByTotalOrder x y   | x < y = LT
src/Numeric/Floating/IEEE/Internal/NaN.hs view
@@ -35,6 +35,8 @@   -- Returns @True@ if the operand is a signaling NaN.   --   -- IEEE 754 @isSignaling@ operation.+  --+  -- Warning: GHC's optimizer is not aware of signaling NaNs.   isSignaling :: a -> Bool   isSignaling x = classify x == SignalingNaN @@ -73,6 +75,9 @@    -- |   -- Comparison with IEEE 754 @totalOrder@ operation.+  --+  -- Floating-point numbers should be ordered as,+  -- \(-\mathrm{qNaN} < -\mathrm{sNaN} < -\infty < \text{negative reals} < -0 < +0 < \text{positive reals} < +\infty < +\mathrm{sNaN} < +\mathrm{qNaN}\).   compareByTotalOrder :: a -> a -> Ordering   compareByTotalOrder = compareByTotalOrderDefault @@ -98,7 +103,7 @@   | x == y = if x == 0 then                compare (isNegativeZero y) (isNegativeZero x)              else-               EQ -- TODO: non-canonical?+               EQ -- TODO: cohort?   | otherwise = compare (isSignMinus y) (isSignMinus x)                 <> let r = compare (isNaN x) (isNaN y) -- number < +NaN                            <> compare (isSignaling y) (isSignaling x) -- +(signaling NaN) < +(quiet NaN)
test/HalfSpec.hs view
@@ -51,10 +51,10 @@ isInfiniteWorkaround :: (Half -> Property) -> (Half -> Property) isInfiniteIsKnownToBeBuggy :: Bool #if MIN_VERSION_half(0,3,1)--- I hope https://github.com/ekmett/half/issues/23 is fixed before the next releaso isInfiniteWorkaround = id isInfiniteIsKnownToBeBuggy = False #else+-- Workaround for https://github.com/ekmett/half/issues/23 isInfiniteWorkaround f x = not (isNaN x) ==> f x isInfiniteIsKnownToBeBuggy = True #endif