Re: [Haskell-cafe] floating point operations and representation
On Wed, Mar 12, 2008 at 9:27 PM, Don Stewart [EMAIL PROTECTED] wrote: You could consider binding directly to the C functions, if needed, {-# OPTIONS -fffi -#include math.h #-} import Foreign.C.Types foreign import ccall unsafe math.h log10 c_log10 :: CDouble - CDouble log10 :: Double - Double log10 x = realToFrac (c_log10 (realToFrac x)) Actually, you could almost certainly just use foreign import ccall unsafe math.h log10 log10 :: Double - Double since in ghc CDouble and Double are identical. It's a bit sloppier, but shouldn't cause any trouble. And I've no idea how realToFrac is implemented, but would worry about it behaving oddly... for instance when given NaNs. David ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re[2]: [Haskell-cafe] floating point operations and representation
Hello David, Monday, March 17, 2008, 7:59:09 PM, you wrote: foreign import ccall unsafe math.h log10 c_log10 :: CDouble - CDouble log10 :: Double - Double log10 x = realToFrac (c_log10 (realToFrac x)) It's a bit sloppier, but shouldn't cause any trouble. And I've no idea how realToFrac is implemented, but would worry about it behaving oddly... for instance when given NaNs. it should be nop (no operation) in such cases -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] floating point operations and representation
On 17 Mar 2008, [EMAIL PROTECTED] wrote: Hello David, Monday, March 17, 2008, 7:59:09 PM, you wrote: foreign import ccall unsafe math.h log10 c_log10 :: CDouble - CDouble log10 :: Double - Double log10 x = realToFrac (c_log10 (realToFrac x)) It's a bit sloppier, but shouldn't cause any trouble. And I've no idea how realToFrac is implemented, but would worry about it behaving oddly... for instance when given NaNs. it should be nop (no operation) in such cases A related issue: http://hackage.haskell.org/trac/ghc/ticket/2110 Presumably everyone is aware of decodeFloat :: (RealFloat a) = a - (Integer, Int) which really is a canonical representation of a floating point number. As for realToFrac, this really isn't okay: *GHCi 0/0 NaN *GHCi realToFrac (0/0) -Infinity Also, this one might surprise a few people. *GHCi realToFrac (realToFrac 0.2 :: Ratio Int) -Infinity *GHCi realToFrac 0.2 :: Ratio Int (-858993459)%0 Jed pgpkz5RfasGnc.pgp Description: PGP signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] floating point operations and representation
daveroundy: On Wed, Mar 12, 2008 at 9:27 PM, Don Stewart [EMAIL PROTECTED] wrote: You could consider binding directly to the C functions, if needed, {-# OPTIONS -fffi -#include math.h #-} import Foreign.C.Types foreign import ccall unsafe math.h log10 c_log10 :: CDouble - CDouble log10 :: Double - Double log10 x = realToFrac (c_log10 (realToFrac x)) Actually, you could almost certainly just use foreign import ccall unsafe math.h log10 log10 :: Double - Double since in ghc CDouble and Double are identical. It's a bit sloppier, but shouldn't cause any trouble. And I've no idea how realToFrac is implemented, but would worry about it behaving oddly... for instance when given NaNs. It's a no-op (from the core I was looking at), and then you're not worrying about coercing newtypes. -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] floating point operations and representation
On Mon, Mar 17, 2008 at 12:59:09PM -0400, David Roundy wrote: foreign import ccall unsafe math.h log10 log10 :: Double - Double since in ghc CDouble and Double are identical. It's a bit sloppier, but shouldn't cause any trouble. And I've no idea how realToFrac is implemented, but would worry about it behaving oddly... for instance when given NaNs. Yes. 'realToFrac' is inherently pretty broken and should be avoided whenever possible. It is not all all obvious to me what the correct primitive should be.. but we really should do something better for haskell'. relying on RULES firing as ghc currently does doesn't seem ideal.. hmm.. maybe a 'FloatMax' type and have 'fromFloatMax' and 'toFloatMax' in 'Fractional' and 'Real' respectively? hmm.. hc has 'fromDouble' and 'toDouble' there, but jhc also supports a 'Float128' type (when the underlying hardware does). so this still isn't quite right. John -- John Meacham - ⑆repetae.net⑆john⑈ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] floating point operations and representation
On Wed, 12 Mar 2008, Don Stewart wrote: I am under the restriction that I need to write Haskell programs using Double which mimic existing C/C++ programs or generated data sets, and get the same answers. (It's silly, but take it as a given requirement.) If the C programs are using log2, then I need log2 in the Haskell, or else I run the risk of not producing the same answers. Hey Jacob, Just to make life super simple, I packaged up a binding to the basic math.h library for Doubles. You can find the library here: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/cmath For example, Prelude Foreign.C.Math.Double.log10 5 0.6989700043360189 Prelude log 5 / log 10 0.6989700043360187 You may want to write a RULES pragma which replaces occurences of 'logBase 2' and 'logBase 10' by their specialised counterparts. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] floating point operations and representation
Jacob Schwartz [EMAIL PROTECTED] writes: A test on IEEE computers (x86 and x86-64), shows that for a range of 64-bit double values, the answers in C do differ (in the last bit) if you use log2(x) and log10(x) versus log (x) / log(2) and log(x) / log(10). I think this may also depend on C compiler and optimization level. Perhaps now everybody uses SSE to do math, but earlier Intel FPU architectures did floating point with 80-bit registers, so the accuracy of the result could depend on whether an intermediate result was flushed to memory (by a context switch). Equality on floating point is tricky, if I were you, I'd round the results before comparing. -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] floating point operations and representation
Wow, you have a tough mission if you want to replicate the bit level answers for double (btw, hi Jacob). Libraries differ for transcendental function, and even worse, CPUs differ. You may get different answers on an Intel and and AMD. That said, I think your best bet is to import log2 and log10 from C and use those. Haskell sadly lacks an efficient way to go from a Double to its bit pattern. :( -- Lennart On Thu, Mar 13, 2008 at 12:35 AM, Jacob Schwartz [EMAIL PROTECTED] wrote: I have two questions about using the Double data type and the operations in the Floating typeclass on a computer that uses IEEE floating point numbers. I notice that the Floating class only provides log (presumably log base 'e') and logBase (which, in the latest source that I see for GHC is defined as log y / log x). However, in C, the math.h library provides specific log2 and log10 functions, for extra precision. A test on IEEE computers (x86 and x86-64), shows that for a range of 64-bit double values, the answers in C do differ (in the last bit) if you use log2(x) and log10(x) versus log (x) / log(2) and log(x) / log(10). I am under the restriction that I need to write Haskell programs using Double which mimic existing C/C++ programs or generated data sets, and get the same answers. (It's silly, but take it as a given requirement.) If the C programs are using log2, then I need log2 in the Haskell, or else I run the risk of not producing the same answers. My first thought is to import log2 and log10 through the FFI. I was wondering if anyone on Haskell-Cafe has already done this and/or has a better suggestion about how to get specialized log2 and log10 (among the many specialized functions that the math.h library provides, for better precision -- for now, I'm just concerned with log2 and log10). My second question is how to get at the IEEE bit representation for a Double. I am already checking isIEEE n in my source code (and floatRadix n == 2). So I know that I am operating on hardware that implements floating point numbers by the IEEE standard. I would like to get at the 64 bits of a Double. Again, I can convert to a CDouble and use the FFI to wrap a C function which casts the double to a 64-bit number and returns it. But I'm wondering if there's not a better way to do this natively in Haskell/GHC (perhaps some crazy use of the Storable typeclass?). Or if someone has already tackled this problem with FFI, that would be interesting to know. Thanks. Jacob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] floating point operations and representation
On Mar 12, 2008, at 8:35 PM, Jacob Schwartz wrote: My second question is how to get at the IEEE bit representation for a Double. My (rhetorical) question on this front isn't how do I get the representation, but why is it so hard and non-portable to get the representation sensibly? A candidate for standardization, surely? -Jan-Willem Maessen ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] floating point operations and representation
On Thu, 13 Mar 2008, Lennart Augustsson wrote: Wow, you have a tough mission if you want to replicate the bit level answers for double (btw, hi Jacob). Libraries differ for transcendental function, and even worse, CPUs differ. You may get different answers on an Intel and and AMD. That said, I think your best bet is to import log2 and log10 from C and use those. Haskell sadly lacks an efficient way to go from a Double to its bit pattern. :( You can do nasty casting using STArray: http://slavepianos.org/rd/sw/sw-78/Sound/OpenSoundControl/Cast.hs ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] floating point operations and representation
On Thu, Mar 13, 2008 at 1:35 AM, Jacob Schwartz [EMAIL PROTECTED] wrote: I have two questions about using the Double data type and the operations in the Floating typeclass on a computer that uses IEEE floating point numbers. I notice that the Floating class only provides log (presumably log base 'e') and logBase (which, in the latest source that I see for GHC is defined as log y / log x). However, in C, the math.h library provides specific log2 and log10 functions, for extra precision. A test on IEEE computers (x86 and x86-64), shows that for a range of 64-bit double values, the answers in C do differ (in the last bit) if you use log2(x) and log10(x) versus log (x) / log(2) and log(x) / log(10). I am under the restriction that I need to write Haskell programs using Double which mimic existing C/C++ programs or generated data sets, and get the same answers. (It's silly, but take it as a given requirement.) If the C programs are using log2, then I need log2 in the Haskell, or else I run the risk of not producing the same answers. My first thought is to import log2 and log10 through the FFI. I was wondering if anyone on Haskell-Cafe has already done this and/or has a better suggestion about how to get specialized log2 and log10 (among the many specialized functions that the math.h library provides, for better precision -- for now, I'm just concerned with log2 and log10). The RULES pragma + FFI solution (as suggested by Henning) seems to be the most sensible one so far. My second question is how to get at the IEEE bit representation for a Double. I am already checking isIEEE n in my source code (and floatRadix n == 2). So I know that I am operating on hardware that implements floating point numbers by the IEEE standard. I would like to get at the 64 bits of a Double. Again, I can convert to a CDouble and use the FFI to wrap a C function which casts the double to a 64-bit number and returns it. But I'm wondering if there's not a better way to do this natively in Haskell/GHC (perhaps some crazy use of the Storable typeclass?). Posted in a a previous haskell-cafe message [1] {-# LANGUAGE MagicHash #-} import Data.Int import GHC.Exts foo :: Double - Int64 --ghc only foo (D# x) = I64# (unsafeCoerce# x) [1] http://www.haskell.org/pipermail/haskell-cafe/2008-February/04.html ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] floating point operations and representation
On Mar 13, 2008, at 5:12 , Ketil Malde wrote: Perhaps now everybody uses SSE to do math, but earlier Intel FPU architectures did floating point with 80-bit registers, so the accuracy of the result could depend on whether an intermediate result was flushed to memory (by a context switch). Double operations in IO, anyone? :/ -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] floating point operations and representation
I have two questions about using the Double data type and the operations in the Floating typeclass on a computer that uses IEEE floating point numbers. I notice that the Floating class only provides log (presumably log base 'e') and logBase (which, in the latest source that I see for GHC is defined as log y / log x). However, in C, the math.h library provides specific log2 and log10 functions, for extra precision. A test on IEEE computers (x86 and x86-64), shows that for a range of 64-bit double values, the answers in C do differ (in the last bit) if you use log2(x) and log10(x) versus log (x) / log(2) and log(x) / log(10). I am under the restriction that I need to write Haskell programs using Double which mimic existing C/C++ programs or generated data sets, and get the same answers. (It's silly, but take it as a given requirement.) If the C programs are using log2, then I need log2 in the Haskell, or else I run the risk of not producing the same answers. My first thought is to import log2 and log10 through the FFI. I was wondering if anyone on Haskell-Cafe has already done this and/or has a better suggestion about how to get specialized log2 and log10 (among the many specialized functions that the math.h library provides, for better precision -- for now, I'm just concerned with log2 and log10). My second question is how to get at the IEEE bit representation for a Double. I am already checking isIEEE n in my source code (and floatRadix n == 2). So I know that I am operating on hardware that implements floating point numbers by the IEEE standard. I would like to get at the 64 bits of a Double. Again, I can convert to a CDouble and use the FFI to wrap a C function which casts the double to a 64-bit number and returns it. But I'm wondering if there's not a better way to do this natively in Haskell/GHC (perhaps some crazy use of the Storable typeclass?). Or if someone has already tackled this problem with FFI, that would be interesting to know. Thanks. Jacob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] floating point operations and representation
quark: I have two questions about using the Double data type and the operations in the Floating typeclass on a computer that uses IEEE floating point numbers. I notice that the Floating class only provides log (presumably log base 'e') and logBase (which, in the latest source that I see for GHC is defined as log y / log x). However, in C, the math.h library provides specific log2 and log10 functions, for extra precision. A test on IEEE computers (x86 and x86-64), shows that for a range of 64-bit double values, the answers in C do differ (in the last bit) if you use log2(x) and log10(x) versus log (x) / log(2) and log(x) / log(10). You could consider binding directly to the C functions, if needed, {-# OPTIONS -fffi -#include math.h #-} import Foreign.C.Types foreign import ccall unsafe math.h log10 c_log10 :: CDouble - CDouble log10 :: Double - Double log10 x = realToFrac (c_log10 (realToFrac x)) main = mapM_ (print . log10) [1..10] Also, is there any difference if you compile with -fvia-C or -fexcess-precision (or both)? My second question is how to get at the IEEE bit representation for a Double. I am already checking isIEEE n in my source code (and floatRadix n == 2). So I know that I am operating on hardware that implements floating point numbers by the IEEE standard. I would like to get at the 64 bits of a Double. Again, I can convert to a CDouble and use the FFI to wrap a C function which casts the double to a 64-bit number and returns it. But I'm wondering if there's not a better way to do this natively in Haskell/GHC (perhaps some crazy use of the Storable typeclass?). Or if someone has already tackled this problem with FFI, that would be interesting to know. The FFI is a good way. You can just bind to any C code linked with your code. There's some similar code for messing with doubles and longs in the mersenne-random package you might be able to use for inspiration: http://code.haskell.org/~dons/code/mersenne-random/ -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] floating point operations and representation
I am under the restriction that I need to write Haskell programs using Double which mimic existing C/C++ programs or generated data sets, and get the same answers. (It's silly, but take it as a given requirement.) If the C programs are using log2, then I need log2 in the Haskell, or else I run the risk of not producing the same answers. Hey Jacob, Just to make life super simple, I packaged up a binding to the basic math.h library for Doubles. You can find the library here: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/cmath For example, Prelude Foreign.C.Math.Double.log10 5 0.6989700043360189 Prelude log 5 / log 10 0.6989700043360187 Enjoy! -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe