#5683 closed bug (fixed)
bug in signum function
Reported by: | tristes_tigres | Owned by: | |
---|---|---|---|
Priority: | normal | Milestone: | 7.6.1 |
Component: | Prelude | Version: | 7.0.3 |
Keywords: | Cc: | anton.nik@…, mihai.maruseac@… | |
Operating System: | Unknown/Multiple | Architecture: | Unknown/Multiple |
Type of failure: | Other | Test Case: | |
Blocked By: | Blocking: | ||
Related Tickets: | Differential Rev(s): | ||
Wiki Page: |
Description
IEE754 standard states, that every floating point operation involving a NaN should produce NaN. However, in GHC 7.0.3 (in the current Haskell platform) evaluating
signum (0.0/0.0)
produces -1
Change History (14)
comment:1 Changed 8 years ago by
comment:2 Changed 8 years ago by
Thoughts about the right (meaning, in the spirit of IEEE754) way to fix this:
Operations truncate, round, ceiling and floor on a floating-point type should return floating-point type, not integral. The operation of rounding need not and should not be combined with type conversion.
comment:3 Changed 8 years ago by
difficulty: | → Unknown |
---|---|
Milestone: | → 7.6.1 |
Thanks for the report.
I think we do need truncate et al to be able to return integral types, though: You need to combine them with the type conversion in order to describe what sort of type conversion you want (e.g. should 7.7 be converted to 7 or 8?).
comment:4 Changed 8 years ago by
I don't quite understand what you're saying.
"(e.g. should 7.7 be converted to 7 or 8?)."
That is determined by the function you're using: round, floor or ceil. In the context of arithmetic operations, which way you round, say, 7.5, is determined by IEEE rounding-mode flags.
I think we do need truncate et al to be able to return integral types, though:
I see two problems with that: a) Handling of special types: Inf, NaN. They are valid floating-point types, raisig exception on rounding them disagrees with what standard says (and the current way they're handled by Prelude is even worse) b) Making output of round into integral will require conversion back to floating-point in some typical floating-point computations. For instance, take computing of a sine. As a first step, argument is reduced to the interval [0, pi/4] (and then rational approximation is used). Reduction involves rounding the floating-point result of the division by pi. There's abslutely no reason to convert it to integral.
(I speak from floating-point standard perspective)
comment:5 Changed 8 years ago by
Cc: | anton.nik@… added |
---|
comment:6 Changed 7 years ago by
Cc: | mihai.maruseac@… added |
---|
comment:9 Changed 7 years ago by
Resolution: | → duplicate |
---|---|
Status: | new → closed |
comment:10 Changed 4 years ago by
Resolution: | duplicate |
---|---|
Status: | closed → new |
Re-opening because it's not entirely a duplicate. Bug #3070 is blocked because of some fundamental issues with how Haskell handles floating-point, but I don't believe those issues preclude fixing the signum function to preserve NaN.
comment:11 Changed 4 years ago by
Aside from preserving NaN, there's also a question of whether -0.0 should be mapped to 0.0 or left alone. IMHO it should be left unchanged because it permits a nice symmetric implementation:
signum x | x > 0 = 1 | x < 0 = -1 | otherwise = x
Aside: there's some good discussion here of why Python has no signum function. I guess that ship has sailed for Haskell, but it makes me inclined to think there's no universally correct definition, which is why I think having a pretty implementation is as good a reason as any to settle on a definition for the edge cases.
comment:12 follow-up: 13 Changed 4 years ago by
Resolution: | → fixed |
---|---|
Status: | new → closed |
This was fixed in 7.10.1. signum (-0.0)
is -0.0
now as well.
comment:13 Changed 4 years ago by
Replying to rwbarton:
This was fixed in 7.10.1.
signum (-0.0)
is-0.0
now as well.
Just tried it on haskell.org page
signum(0.0/0.0)
-1.0 :: Fractional a => a
Doesn't look right to me. What version of Haskell web demo is using?
comment:14 Changed 4 years ago by
This was fixed in commit d9a20573f473cc7389004470999b8a318aa6b3f2:
Author: Alexander Berntsen <alexander@plaimi.net> Date: Mon Aug 18 21:43:33 2014 -0500 Make Prelude.signum handle -0.0 correctly (#7858) Summary: Make the `Float` and `Double` implementations of `signum` handle -0.0 correctly per IEEE-754. This, together with "Make Prelude.abs handle -0.0 correctly (#7858)", fixes Trac #7858. Depends on D145 Signed-off-by: Alexander Berntsen <alexander@plaimi.net> Test Plan: signum of (-0.0) should be (-0.0) not 0.0. Test program: main = putStrLn $ p ++ " " ++ n where f = show . signum p = f (-0.0 :: Double) n = f (0.0 :: Double) Reviewers: ekmett, hvr, rwbarton, austin Reviewed By: austin Subscribers: phaskell, simonmar, relrod, ezyang, carter Differential Revision: https://phabricator.haskell.org/D148 GHC Trac Issues: #7858
And
round (0.0/0.0)
produces a very large negative number.