scientific-notation 0.1.5.0 → 0.1.6.0
raw patch · 3 files changed
+57/−27 lines, 3 filesdep ~basedep ~natural-arithmetic
Dependency ranges changed: base, natural-arithmetic
Files
- CHANGELOG.md +5/−0
- scientific-notation.cabal +3/−3
- src/Data/Number/Scientific.hs +49/−24
CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for scientific-notation +## 0.1.6.0 -- 2023-??-??O++* Support GHC 9.4 and 9.6. Drop support for GHCs older than 9.4.+* Add `fromInt` and `fromInt(8|16|32|64)`.+ ## 0.1.5.0 -- 2022-07-15 * Support GHC 9.2.
scientific-notation.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: scientific-notation-version: 0.1.5.0+version: 0.1.6.0 synopsis: Scientific notation intended for tokenization description: This library provides a type used to represent a number in@@ -48,11 +48,11 @@ library exposed-modules: Data.Number.Scientific build-depends:- , base >=4.12 && <5+ , base >=4.17.1 && <5 , bytebuild >=0.3.5 && <0.4 , bytesmith >=0.3 && <0.4 , byteslice >=0.2.6 && <0.3- , natural-arithmetic >=0.1.1 && <0.2+ , natural-arithmetic >=0.1.1 && <0.3 , text-short >=0.1.3 , primitive >=0.7.1 , bytestring >=0.10.12
src/Data/Number/Scientific.hs view
@@ -18,6 +18,11 @@ , fromWord16 , fromWord32 , fromWord64+ , fromInt+ , fromInt8+ , fromInt16+ , fromInt32+ , fromInt64 -- * Consume , toWord , toWord8@@ -51,21 +56,19 @@ import Prelude hiding (negate) import Control.Monad.ST (runST)-import GHC.Exts (Int#,Word#,Int(I#),(+#))-import GHC.Word.Compat-import GHC.Int.Compat+import Data.ByteString.Short.Internal (ShortByteString(SBS)) import Data.Bytes.Builder (Builder) import Data.Bytes.Parser.Unsafe (Parser(..))+import Data.Bytes.Types (Bytes(Bytes)) import Data.Fixed (Fixed(MkFixed),HasResolution) import Data.Primitive (ByteArray(ByteArray)) import Data.Text.Short (ShortText)-import Data.ByteString.Short.Internal (ShortByteString(SBS))-import Data.Bytes.Types (Bytes(Bytes))+import GHC.Exts (Int#,Word#,(+#),intToInt64#,int64ToInt#)+import GHC.Int.Compat+import GHC.Word.Compat import qualified Arithmetic.Nat as Nat-import qualified Data.Fixed as Fixed import qualified Data.Bytes as Bytes-import qualified Data.Bytes.Types as BT import qualified Data.Bytes.Builder as Builder import qualified Data.Bytes.Builder.Bounded as BB import qualified Data.Bytes.Builder.Bounded.Unsafe as BBU@@ -73,6 +76,8 @@ import qualified Data.Bytes.Parser as Parser import qualified Data.Bytes.Parser.Latin as Latin import qualified Data.Bytes.Parser.Unsafe as Unsafe+import qualified Data.Bytes.Types as BT+import qualified Data.Fixed as Fixed import qualified Data.Primitive as PM import qualified Data.Text.Short.Unsafe as TS import qualified GHC.Exts as Exts@@ -128,7 +133,7 @@ eqLargeScientific :: LargeScientific -> LargeScientific -> Bool eqLargeScientific a b =- let LargeScientific cA eA = largeNormalize a + let LargeScientific cA eA = largeNormalize a LargeScientific cB eB = largeNormalize b in cA == cB && eA == eB @@ -210,7 +215,7 @@ {-# inline toInt64 #-} toInt64 (Scientific (I# coeff) (I# e) largeNum) = case toInt# coeff e largeNum of (# (# #) | #) -> Nothing- (# | i #) -> Just (I64# i)+ (# | i #) -> Just (I64# (intToInt64# i)) -- | This works even if the number has a fractional component. For example: --@@ -227,7 +232,7 @@ roundShiftedToInt64 (I# adj) (Scientific (I# coeff) (I# e) largeNum) = case roundToInt# coeff e adj largeNum of (# (# #) | #) -> Nothing- (# | i #) -> Just (I64# i)+ (# | i #) -> Just (I64# (intToInt64# i)) -- | Convert a 64-bit unsigned word to a 'Scientific'. fromWord64 :: Word64 -> Scientific@@ -237,6 +242,26 @@ let !b = LargeScientific (fromIntegral w) 0 in Scientific 0 minBound b +fromInt :: Int -> Scientific+{-# inline fromInt #-}+fromInt coeff = Scientific coeff 0 zeroLarge++fromInt8 :: Int8 -> Scientific+{-# inline fromInt8 #-}+fromInt8 coeff = Scientific (fromIntegral coeff) 0 zeroLarge++fromInt16 :: Int16 -> Scientific+{-# inline fromInt16 #-}+fromInt16 coeff = Scientific (fromIntegral coeff) 0 zeroLarge++fromInt32 :: Int32 -> Scientific+{-# inline fromInt32 #-}+fromInt32 coeff = Scientific (fromIntegral coeff) 0 zeroLarge++fromInt64 :: Int64 -> Scientific+{-# inline fromInt64 #-}+fromInt64 coeff = Scientific (fromIntegral coeff) 0 zeroLarge+ -- | Convert an 8-bit unsigned word to a 'Scientific'. fromWord8 :: Word8 -> Scientific {-# inline fromWord8 #-}@@ -258,25 +283,25 @@ greaterThanInt64 (Scientific coeff0@(I# coeff0# ) e0 large0) tgt@(I64# tgt# ) | e0 == minBound = largeGreaterThanInt64 large0 tgt | coeff0 == 0 = 0 > tgt- | e0 == 0 = I64# coeff0# > tgt+ | e0 == 0 = I64# (intToInt64# coeff0#) > tgt | coeff0 > 0 = if | tgt <= 0 -> True | e0 > 0 -> case smallToInt coeff0 e0 of (# (# #) | #) -> True- (# | i# #) -> I64# i# > tgt+ (# | i# #) -> I64# (intToInt64# i#) > tgt -- In last case, e0 is less than zero.- | otherwise -> case posIntExp10 (I# tgt#) (Prelude.negate e0) of+ | otherwise -> case posIntExp10 (I# (int64ToInt# tgt#)) (Prelude.negate e0) of (# (# #) | #) -> False- (# | i# #) -> I64# coeff0# > I64# i#+ (# | i# #) -> I64# (intToInt64# coeff0#) > I64# (intToInt64# i#) | otherwise = -- Coefficent is negative if | tgt >= 0 -> False | e0 > 0 -> case smallToInt coeff0 e0 of (# (# #) | #) -> False- (# | i# #) -> I64# i# > tgt+ (# | i# #) -> I64# (intToInt64# i#) > tgt -- In last case, e0 is less than zero.- | otherwise -> case negIntExp10 (I# tgt#) (Prelude.negate e0) of+ | otherwise -> case negIntExp10 (I# (int64ToInt# tgt#)) (Prelude.negate e0) of (# (# #) | #) -> True- (# | i# #) -> I64# coeff0# > I64# i#+ (# | i# #) -> I64# (intToInt64# coeff0#) > I64# (intToInt64# i#) largeGreaterThanInt64 :: LargeScientific -> Int64 -> Bool largeGreaterThanInt64 large0@(LargeScientific coeff e) !tgt@@ -286,7 +311,7 @@ if | tgt <= 0 -> True | e > 0 -> case largeToInt large0 of (# (# #) | #) -> True- (# | i# #) -> I64# i# > tgt+ (# | i# #) -> I64# (intToInt64# i#) > tgt | otherwise -> case posSciLowerBound False coeff e of Exactly n -> n > fromIntegral @Int64 @Integer tgt LowerBoundedMagnitude n -> (n+1) > fromIntegral @Int64 @Integer tgt@@ -294,11 +319,11 @@ if | tgt >= 0 -> False | e > 0 -> case largeToInt large0 of (# (# #) | #) -> False- (# | i# #) -> I64# i# > tgt+ (# | i# #) -> I64# (intToInt64# i#) > tgt | otherwise -> case posSciLowerBound False coeff e of Exactly n -> n > fromIntegral @Int64 @Integer tgt LowerBoundedMagnitude n -> n > fromIntegral @Int64 @Integer tgt- + -- | Expose the non-normalized exponent and coefficient. withExposed :: (Int -> Int -> a)@@ -347,7 +372,7 @@ toWord8# :: Int# -> Int# -> LargeScientific -> (# (# #) | Word# #) {-# noinline toWord8# #-}-toWord8# coefficient0# exponent0# large0 = +toWord8# coefficient0# exponent0# large0 = toSmallHelper smallToWord8 largeToWord8 coefficient0# exponent0# large0 @@ -871,7 +896,7 @@ -> Parser e s Scientific parserNegatedTrailingUtf8Bytes e (I# leader) = boxScientific (parserNegatedTrailingUtf8Bytes# e leader)--- +-- -- parserTrailingUtf8Bytes# :: -- e -- Error message -- -> Parser e s Scientific#@@ -1151,7 +1176,7 @@ -- Precondition: exponent is negative. -- This is convoluted, so if a reader of this code thinks of a better--- way to do this, feel free to PR a more simple replacement. +-- way to do this, feel free to PR a more simple replacement. encodePosCoeffNegExp :: Word -> Int -> Bytes encodePosCoeffNegExp !w !e = runST $ do dst <- PM.newByteArray 128@@ -1173,7 +1198,7 @@ -- Precondition: exponent is negative. -- This is convoluted, so if a reader of this code thinks of a better--- way to do this, feel free to PR a more simple replacement. +-- way to do this, feel free to PR a more simple replacement. encodeNegCoeffNegExp :: Word -> Int -> Bytes encodeNegCoeffNegExp !w !e = runST $ do dst <- PM.newByteArray 128