Skip to content

Commit ab5ebda

Browse files
Fix signum implementation (#280)
* Fix signum implementation * Add changelog entry * Reimplement w/o 'otherwise' * Apply suggestions from code review Co-authored-by: Harry Garrood <[email protected]> * Update src/Data/Ord.purs Co-authored-by: Harry Garrood <[email protected]> * Adjust doc comment to use sized zeros rendering * Add test for signum * Add missing period. Co-authored-by: Harry Garrood <[email protected]> * Ensure signum test functions correctly * Do test via `show (1.0/zero)` with clarifying test Co-authored-by: Harry Garrood <[email protected]>
1 parent 3042bcb commit ab5ebda

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Breaking changes:
88
- Migrated FFI to ES Modules (#287 by @kl0tl and @JordanMartinez)
99
- Change Generic Rep's `NoConstructors` to newtype `Void` (#282 by @JordanMartinez)
1010
- Replaced polymorphic proxies with monomorphic `Proxy` (#281, #288 by @JordanMartinez)
11+
- Fix `signum zero` to return `zero` (#280 by @JordanMartinez)
1112

1213
New features:
1314

src/Data/Ord.purs

+9-3
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,16 @@ between low hi x
216216
abs :: forall a. Ord a => Ring a => a -> a
217217
abs x = if x >= zero then x else negate x
218218

219-
-- | The sign function; always evaluates to either `one` or `negate one`. For
220-
-- | any `x`, we should have `signum x * abs x == x`.
219+
-- | The sign function; returns `one` if the argument is positive,
220+
-- | `negate one` if the argument is negative, or `zero` if the argument is `zero`.
221+
-- | For floating point numbers with signed zeroes, when called with a zero,
222+
-- | this function returns the argument in order to preserve the sign.
223+
-- | For any `x`, we should have `signum x * abs x == x`.
221224
signum :: forall a. Ord a => Ring a => a -> a
222-
signum x = if x >= zero then one else negate one
225+
signum x =
226+
if x < zero then negate one
227+
else if x > zero then one
228+
else x
223229

224230
-- | The `Ord1` type class represents totally ordered type constructors.
225231
class Eq1 f <= Ord1 f where

test/Test/Main.purs

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Test.Main where
22

33
import Prelude
44
import Data.HeytingAlgebra (ff, tt, implies)
5-
import Data.Ord (abs)
5+
import Data.Ord (abs, signum)
66
import Test.Data.Generic.Rep (testGenericRep)
77
import Test.Utils (AlmostEff, assert)
88

@@ -15,6 +15,7 @@ main = do
1515
testIntDegree
1616
testRecordInstances
1717
testGenericRep
18+
testSignum
1819

1920
foreign import testNumberShow :: (Number -> String) -> AlmostEff
2021

@@ -151,3 +152,10 @@ testRecordInstances = do
151152
assert "Record top" $
152153
(top :: { a :: Boolean }).a
153154
== top
155+
156+
testSignum :: AlmostEff
157+
testSignum = do
158+
assert "Clarifies what 'signum positive zero' test is doing" $ show (1.0/0.0) == "Infinity"
159+
assert "signum positive zero" $ show (1.0/(signum 0.0)) == "Infinity"
160+
assert "Clarifies what 'signum negative zero' test is doing" $ show (1.0/(-0.0)) == "-Infinity"
161+
assert "signum negative zero" $ show (1.0/(signum (-0.0))) == "-Infinity"

0 commit comments

Comments
 (0)