diff --git a/docs/Data/BigInt.md b/docs/Data/BigInt.md index 0569faa..5a80037 100644 --- a/docs/Data/BigInt.md +++ b/docs/Data/BigInt.md @@ -29,6 +29,14 @@ fromInt :: Int -> BigInt Convert an integer to a BigInt. +#### `fromNumber` + +``` purescript +fromNumber :: Number -> BigInt +``` + +Convert a Number to a BigInt. The fractional part is truncated. + #### `toNumber` ``` purescript diff --git a/src/Data/BigInt.js b/src/Data/BigInt.js index 36567ed..057a43d 100644 --- a/src/Data/BigInt.js +++ b/src/Data/BigInt.js @@ -19,6 +19,15 @@ exports["fromBase'"] = function(just) { exports.fromInt = bigInt; +function truncate(n) { + if (n > 0) return Math.floor(n); + return Math.ceil(n); +} + +exports.fromNumber = function(x) { + return bigInt(truncate(x)); +}; + exports.toBase = function(base) { return function (x) { return x.toString(base); diff --git a/src/Data/BigInt.purs b/src/Data/BigInt.purs index 7d3aff7..1eaa684 100644 --- a/src/Data/BigInt.purs +++ b/src/Data/BigInt.purs @@ -4,6 +4,7 @@ module Data.BigInt , fromString , fromBase , fromInt + , fromNumber , toString , toBase , abs @@ -38,6 +39,9 @@ foreign import fromBase' :: forall a. (a -> Maybe a) -- | Convert an integer to a BigInt. foreign import fromInt :: Int -> BigInt +-- | Convert a Number to a BigInt. The fractional part is truncated. +foreign import fromNumber :: Number -> BigInt + -- | Converts a BigInt to a Number. Loses precision for numbers which are too -- | large. foreign import toNumber :: BigInt -> Number diff --git a/test/Main.purs b/test/Main.purs index 2fdd838..366b04b 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -5,7 +5,8 @@ import Control.Monad.Eff.Console (CONSOLE, log) import Control.Monad.Eff.Exception (EXCEPTION) import Control.Monad.Eff.Random (RANDOM) import Data.Array (filter, range) -import Data.BigInt (BigInt, abs, fromInt, prime, pow, odd, even, fromString, toNumber, fromBase, toBase, toString, not, or, xor, and, shl, shr) +import Data.BigInt (BigInt, abs, fromInt, fromNumber, prime, pow, odd, even, fromString, toNumber, + fromBase, toBase, toString, not, or, xor, and, shl, shr) import Data.Foldable (fold) import Data.Int as Int import Data.Maybe (Maybe(..), fromMaybe) @@ -85,6 +86,14 @@ main = do assert $ (toBase 16 <$> fromString "255") == Just "ff" assert $ toString (fromInt 12345) == "12345" + log "Converting from Number to BigInt" + assert $ fromNumber 0.0 == zero + assert $ fromNumber 3.4 == three + assert $ fromNumber (-3.9) == -three + assert $ fromNumber 1.0e7 == fromInt 10000000 + assert $ Just (fromNumber 1.0e47) == fromString "1e47" + quickCheck (\x -> fromInt x == fromNumber (Int.toNumber x)) + log "Conversions between String, Int and BigInt should not loose precision" quickCheck (\n -> fromString (show n) == Just (fromInt n)) quickCheck (\n -> Int.toNumber n == toNumber (fromInt n))