[GHC] #8823: showFloat for higher precision types produces strange results for some values

#8823: showFloat for higher precision types produces strange results for some values --------------------------+------------------------------------------------ Reporter: axman6 | Owner: Type: bug | Status: new Priority: low | Milestone: Component: | Version: 7.8.1-rc1 Prelude | Operating System: Unknown/Multiple Keywords: | Type of failure: Incorrect result at runtime Architecture: | Test Case: Unknown/Multiple | Blocking: Difficulty: | Unknown | Blocked By: | Related Tickets: | --------------------------+------------------------------------------------ I've written a library which is a quda-double type a la the QD C/C++ package, and showFloat does not behave correctly for numbers with such high precision. My type has ~212 bits of precision, and when using showFloat from Numeric, I get strange results for integer values: {{{ show (1 :: QDouble) = "0.00000000000000000000000000000000000000000000001e47" show (1.1 :: QDouble) = "1.1" show (1000 :: QDouble) = "0.00000000000000000000000000000000000000000000001e50" -- These seems to suggest it happens for any number with only a -- few high bits set to 1 in the result of decodeFloat show (1.125 :: QDouble) = "0.00000000000000000000000000000000000000000000001125e47" show (1.625 :: QDouble) = "0.00000000000000000000000000000000000000000000001625e47" }}} The problem seems to be related to the result of floatDigits, which starts causing problem when it's larger than 56 (floatDigits x, show x): {{{ (56,"1.0") (57,"01.0") (60,"001.0") (212,"0.00000000000000000000000000000000000000000000001e47") }}} My fix has been to use a modified version of showFloat from Numeric by changing the floatToDigits function to include a fix for times when large numbers of zeros are produced: {{{ fixup2 (xs,k) = let (zs,ys) = span (==0) xs in (ys,k-length zs) in fixup2 (map fromIntegral (reverse rds), k) }}} This fixes the symptom but not the issue itself (though it seems like a reasonable thing to have any result returned by floatToDigits. I have attached as minimal test case as I could come up with. Using floatToDigits from Numeric causes the strange behaviour, while floatToDigits' included in the test case does not. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8823 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8823: showFloat for higher precision types produces strange results for some values ------------------------------------------------+-------------------------- Reporter: axman6 | Owner: Type: bug | Status: new Priority: low | Milestone: Component: Prelude | Version: Resolution: | 7.8.1-rc1 Operating System: Unknown/Multiple | Keywords: Type of failure: Incorrect result at runtime | Architecture: Test Case: | Unknown/Multiple Blocking: | Difficulty: | Unknown | Blocked By: | Related Tickets: ------------------------------------------------+-------------------------- Comment (by axman6): To reproduce the bug, try changing the value of floatDigits to ~56 and running `floatToDigits 10 {FOne,FOneThousand,FTwo}`. As can be seen with FPi the correct results are produced. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8823#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8823: showFloat for higher precision types produces strange results for some values ------------------------------------------------+-------------------------- Reporter: axman6 | Owner: Type: bug | Status: closed Priority: low | Milestone: Component: Prelude | Version: Resolution: invalid | 7.8.1-rc1 Operating System: Unknown/Multiple | Keywords: Type of failure: Incorrect result at runtime | Architecture: Test Case: | Unknown/Multiple Blocking: | Difficulty: | Unknown | Blocked By: | Related Tickets: ------------------------------------------------+-------------------------- Changes (by rwbarton): * status: new => closed * resolution: => invalid Comment: Your `RealFloat` instance is invalid. See the documentation for `decodeFloat`:
If decodeFloat x yields (m,n), then x is equal in value to m*b^n^, where b is the floating-point radix, and furthermore, either m and n are both zero or else '''b^(d-1)^ <= abs m < b^d^, where d is the value of floatDigits x'''.
-- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8823#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#8823: showFloat for higher precision types produces strange results for some values ------------------------------------------------+-------------------------- Reporter: axman6 | Owner: Type: bug | Status: closed Priority: low | Milestone: Component: Prelude | Version: Resolution: invalid | 7.8.1-rc1 Operating System: Unknown/Multiple | Keywords: Type of failure: Incorrect result at runtime | Architecture: Test Case: | Unknown/Multiple Blocking: | Difficulty: | Unknown | Blocked By: | Related Tickets: ------------------------------------------------+-------------------------- Comment (by axman6): Hmmm, it seems you're right, but nonetheless my implementation of decodeFloat is the only one that makes sense for my type since it can represent more than 212 bits of data (for example 1.0000000...005 is represented with the doubles 1.0 and 0.5eN, and 0 for the two other doubles]). It seems that perhaps in my case I may need floatDigits to be very large indeed or use another method to show the number. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8823#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC