Skip to content

Commit 7925db1

Browse files
authored
Merge pull request #25 from purescript/non-int-ints
Fix `round`, `ceil`, `floor` for NaN / Infinity inputs
2 parents 4c7c643 + ded42d0 commit 7925db1

File tree

3 files changed

+31
-20
lines changed

3 files changed

+31
-20
lines changed

bower.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
"package.json"
1818
],
1919
"dependencies": {
20-
"purescript-maybe": "^2.0.0",
20+
"purescript-globals": "^2.0.0",
2121
"purescript-math": "^2.0.0",
22+
"purescript-maybe": "^2.0.0",
2223
"purescript-partial": "^1.1.2"
2324
},
2425
"devDependencies": {

src/Data/Int.purs

+15-16
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module Data.Int
55
, round
66
, toNumber
77
, fromString
8-
, Radix()
8+
, Radix
99
, radix
1010
, binary
1111
, octal
@@ -19,19 +19,14 @@ module Data.Int
1919
, pow
2020
) where
2121

22-
import Data.Boolean (otherwise)
23-
import Data.BooleanAlgebra ((&&))
24-
import Data.Bounded (top, bottom)
25-
import Data.Eq ((==), (/=))
26-
import Data.Function ((<<<))
22+
import Prelude
23+
2724
import Data.Int.Bits ((.&.))
28-
import Data.Maybe (Maybe(..), fromJust)
29-
import Data.Ord ((<=), (>=))
25+
import Data.Maybe (Maybe(..), fromMaybe)
26+
import Global (infinity)
3027

3128
import Math as Math
3229

33-
import Partial.Unsafe (unsafePartial)
34-
3530
-- | Creates an `Int` from a `Number` value. The number must already be an
3631
-- | integer and fall within the valid range of values for the `Int` type
3732
-- | otherwise `Nothing` is returned.
@@ -45,28 +40,32 @@ foreign import fromNumberImpl
4540
-> Maybe Int
4641

4742
-- | Convert a `Number` to an `Int`, by taking the closest integer equal to or
48-
-- | less than the argument. Values outside the `Int` range are clamped.
43+
-- | less than the argument. Values outside the `Int` range are clamped, `NaN`
44+
-- | and `Infinity` values return 0.
4945
floor :: Number -> Int
5046
floor = unsafeClamp <<< Math.floor
5147

5248
-- | Convert a `Number` to an `Int`, by taking the closest integer equal to or
53-
-- | greater than the argument. Values outside the `Int` range are clamped.
49+
-- | greater than the argument. Values outside the `Int` range are clamped,
50+
-- | `NaN` and `Infinity` values return 0.
5451
ceil :: Number -> Int
5552
ceil = unsafeClamp <<< Math.ceil
5653

5754
-- | Convert a `Number` to an `Int`, by taking the nearest integer to the
58-
-- | argument. Values outside the `Int` range are clamped.
55+
-- | argument. Values outside the `Int` range are clamped, `NaN` and `Infinity`
56+
-- | values return 0.
5957
round :: Number -> Int
6058
round = unsafeClamp <<< Math.round
6159

6260
-- | Convert an integral `Number` to an `Int`, by clamping to the `Int` range.
63-
-- | This function will throw an error at runtime if the argument is
64-
-- | non-integral.
61+
-- | This function will return 0 if the input is `NaN` or an `Infinity`.
6562
unsafeClamp :: Number -> Int
6663
unsafeClamp x
64+
| x == infinity = 0
65+
| x == -infinity = 0
6766
| x >= toNumber top = top
6867
| x <= toNumber bottom = bottom
69-
| otherwise = unsafePartial (fromJust (fromNumber x))
68+
| otherwise = fromMaybe 0 (fromNumber x)
7069

7170
-- | Converts an `Int` value back into a `Number`. Any `Int` is a valid `Number`
7271
-- | so there is no loss of precision with this function.

test/Test/Data/Int.purs

+14-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import Prelude
55
import Control.Monad.Eff (Eff)
66
import Control.Monad.Eff.Console (CONSOLE, log)
77

8-
import Data.Int (odd, even, fromString, floor, ceil, round, toNumber,
9-
fromNumber, fromStringAs, binary, octal, hexadecimal,
10-
radix, toStringAs, pow)
8+
import Data.Int (odd, even, fromString, floor, ceil, round, toNumber, fromNumber, fromStringAs, binary, octal, hexadecimal, radix, toStringAs, pow)
119
import Data.Maybe (Maybe(..), fromJust)
10+
11+
import Global (nan, infinity)
12+
1213
import Partial.Unsafe (unsafePartial)
1314

1415
import Test.Assert (ASSERT, assert)
@@ -54,6 +55,16 @@ testInt = do
5455
testClamping ceil
5556
testClamping floor
5657

58+
59+
log "round, ceil, and floor should return 0 for NaN and Infinities"
60+
let testNonNumber f = do
61+
assert $ f nan == 0
62+
assert $ f infinity == 0
63+
64+
testNonNumber round
65+
testNonNumber ceil
66+
testNonNumber floor
67+
5768
log "fromString should read integers"
5869
assert $ fromString "0" == Just 0
5970
assert $ fromString "9467" == Just 9467

0 commit comments

Comments
 (0)