Log-domain floating point numbers http://code.haskell.org/~wren/

Version on this page:
LTS Haskell 8.3:
Stackage Nightly 2017-02-28:
Latest on Hackage:
BSD3 licensed by wren gayle romano
Maintained by wren@community.haskell.org

Module documentation for


Hackage version Hackage-Deps TravisCI Build Status CircleCI Build Status

This package provides a type for storing numbers in the log-domain, primarily useful for preventing underflow when multiplying many probabilities as in HMMs and other probabilistic models. The package also provides modules for dealing with floating numbers correctly.

As of version 0.13.3, we've dropped support for Hugs and GHC < 7.8. Nothing major has changed, so they should still work; it's just that they're no longer officially supported. (In practice, GHC 7.6 still works just fine, and is still being tested against. It's just that this support will be droped in the future, once it becomes a burden.) Thus, this version of the library provides a transitional point between backwards compatability and adding new features (see below).

Note that the GitHub repository is just a clone of the Darcs repo. I'm testing out whether to switch things over to GitHub in order to use TravisCI, and an official ticket tracker, etc.


In general, this is a simple package and should be easy to install. The specifics are a bit murky however, since we use CPP and the FFI and want to retain portability, and due to the rapid evolution of Cabal and other development tools. You should be able to use one of the following standard installation methods:

-- With cabal-install and without the source:
$> cabal install logfloat

-- With cabal-install and with the source already:
$> cd logfloat
$> cabal install

-- Without cabal-install, but with the source already:
$> cd logfloat
$> runhaskell Setup.hs configure --user
$> runhaskell Setup.hs build
$> runhaskell Setup.hs haddock --hyperlink-source
$> runhaskell Setup.hs copy
$> runhaskell Setup.hs register

The Haddock step is optional.

FFI Problems

The logfloat package uses the FFI to access functions in libm to improve accuracy. These functions are part of the ISO C 1999 standard and are supported on most systems, however they're not part of the ANSI C standard nor the System V standard and so they might be unavailable on some systems. If you encounter errors during build about not being able to find <math.h>, not having prototypes for functions, or linking errors, then you are probably on such a system.

In order to use pure Haskell and disable the FFI, pass -f-useFFI during the configure phase to disable the useFFI flag. This will degrade the accuracy of certain operations, but should still compile cleanly.

If you run into errors like "error: 'log1p' redeclared as different kind of symbol" this is due to a bug in GHC 6.10.1 where you can't use both -fvia-C and the FFI. This bug should be circumvented for the moment, but resolving it is still a work in progress. See the bug report (which is resolved in GHC 6.10.2):


Windows FFI

The logfloat package builds and installs cleanly with GHC on Windows (without needing Cygwin nor Mingw/Msys), and the installed package can be used in compiled programs without any issues.

However, by default, the package does not work from the GHCi debugger and gives errors like "can't load .so/.DLL for: m (addDLL: could not load DLL)". This is a long-standing issue with GHCi having to do with the fact that, on Windows, the so-called "libm" file does not actually contain anything (as it does on POSIX) and the C functions we use are instead placed in libmingwex.a (which comes bundled with GHC). The problem is that ghc (the compiler) knows to pull in libmingwex.a, whereas ghci (the interactive debugger) does not. All of this is true at least as far back as Windows XP and GHC 6.10.1. Some more information can be found in the ticket:


The most reliable workaround at this point, alas, is to compile the library with FFI support disabled in order to be able to use it in GHCi, and then to recompile with FFI enabled whenever you need to ship a compiled program.

A less-reliable workaround (i.e., needs to be tailored for your system based on your paths, and you'll need to have gcc installed) which avoids the need for recompilation is to generate the DLL yourself by running the following two commands and then placing the resulting m.dll into your path.

ar -x libmingwex.a
gcc -shared *.o -o m.dll


If you want to run the test suite, use the following standard method (with runhaskell Setup.hs in lieu of cabal, if necessary):

$> cd logfloat
$> cabal configure --enable-tests --enable-coverage
$> cabal build
$> cabal test --keep-tix-files

The results of the code coverage are in ./dist/hpc/vanilla/html/logfloat-$VERSION/hpc_index.html. If you're not interested in the coverage of the test suite, then you needn't pass the --enable-coverage nor --keep-tix-files flags. Note that older versions of cabal used the flag name --enable-library-coverage instead of --enable-coverage. And IIRC hpc integration in cabal was broken for ghc-7.6.

Haddock Problems

In Cabal 1.2 there is a bug in the handling of building Haddock documentation when CPP is involved. These issues have been fixed in Cabal 1.6, but here are the instructions if you're on older systems.

In Cabal 1.2 the cpp-options field is not passed to Haddock, and therefore any macros defined there are not seen, which can cause Haddock to fail. The old workaround was to define CPP macros in the ghc-options field which does get passed to Haddock. This is now considered bad style and is forbidden by Hackage. It appears that passing --haddock-option=... or --ghc-option=... flags during configure does not have the same effect as defining the field.

Therefore, in order to properly compile Haddock documentation on Cabal 1.2, you should go into logfloat.cabal and uncomment the ghc-options fields which declare CPP macros -D_USEFFI and -DHUGS__=200609. If you know of a better workaround for this configuration, contact the maintainer.

Building for Hugs (September 2006)

If you're feeling adventurous and want to try and get the library to compile under Hugs, here's how you used to be able to compile things:

runhaskell Setup.hs configure --hugs  \
    --with-cpphs="`which cpphs-hugs`" \
    --ffihugs-options="-98 +o"        \
    --ffihugs-option=-F'cpp -P -traditional -D__HUGS__=200609 -D__USE_FFI__'
runhaskell Setup.hs build
runhaskell Setup.hs copy
runhaskell Setup.hs register

If you need to disable the FFI due to issues with not being able to find , not having prototypes for functions, or linking errors, be sure not to pass -D_USEFFI__ to the cpp filter for ffihugs.

Notably, Hugs installs cpphs under the name "cpphs-hugs" by default. The which command will try to resolve the location, assuming it's on your $PATH. If it isn't, then change the --with-cpphs= flag to point to where cpphs is installed on your system.

Some additional details about difficulties with building for Hugs can be found in this blog post and the bug reports:


And while previous versions of Cabal could build this package (with the above commandline to work around those bugs), Hugs support is broken in Cabal 1.8 (including at least through


Changes: Version 0.13.3+ (2015-03-29) vs 0.12.1 (2010-03-19)

  • Monomorphized logFloat, logToLogFloat, fromLogFloat, and logFromLogFloat: that is, they all take/return Double now. The change was made to help reduce the need for explicit type signatures. It shouldn't really affect most users, since it seems noone was really making use of the polymorphism provided by previous versions. To get the previous behavior back, just explicitly add calls to realToFrac wherever necessary.

  • Fixed some instances to get them to compile under the new role-based type system of GHC 7.10

  • Cleaned up various extraneous rewrite rules, specializations, etc

  • Added the functions sum, product, and pow. Both sum and product preserve more precision than the fold-based definitions in the Prelude. Moreover, sum is much faster than the Prelude version, since it only requires crossing the log/exp boundary n+1 times, instead of 2*(n-1) times. The only downside is that sum requires two passes over the input and thus is not amenable to list fusion.

  • (Version; 2015-08-06) Fixed the Show LogFloat instance to produce parentheses in the right place.

Upcoming changes (0.14+)

  • Since the Data.Number.RealToFrac module is no longer required by any of the others, it will probably be forked off to a separate package in order to improve portability of the rest of the package by removing the need for MPTCs.

  • There's long been clamoring for adding a vector:Data.Vector.Unboxed.Unbox instance. I've been reluctant to add such an instance due to wanting to retain backwards compatibility and portability. Having dropped support for Hugs and older versions of GHC, I'm now willing to add them in.

The logfloat library is conceptually quite simple, and thus to whatever extent possible I'd still like to retain portability to non-GHC compilers. So if you are interested in using logfloat with another compiler/interpreter but run into problems (e.g., due to the type families required by the vector library), please get in touch and I'll try to get things to work.

Compatibility / Portability

The package is compatible with GHC 7.8.3 and 7.10.1. It may still compile with older versions of GHC (or even Hugs!), however they are no longer officially supported.

The package is not compatible with nhc98 and Yhc because Data.Number.RealToFrac uses MPTCs. However, that module is no longer required by any others, and all the other modules should be compatible with these compilers. Thus, it should be fairly easy to port. If you do so, please let me know and I'll try to incorporate support for them.

Changes (2015-08-06):
- Fixed the buggy Show LogFloat instance (2015-05-30):
0.13.3 (2015-03-29):
- Got clean compile on GHC 7.10.1
0.13.2 (2015-03-23):
- Preliminary fixes for dealing with type-roles in GHC 7.10
0.13.1 (2015-03-10):
- Fixed a major bug in sum
0.13 (2015-02-17):
- monomorphized logFloat, logToLogFloat, fromLogFloat, logFromLogFloat
- added sum, product, pow
- cleaned up some extraneous rewrite rules
- removed support for older versions of GHC, in order to clean things up

0.12.1 (2010-03-19):
- Fixed some NaN injection bugs in the Num instance. These would only have been triggered by non-probabilistic uses of LogFloat (i.e., if you used @logFloat infinity@) (2009-04-03):
- Added notes to INSTALL about Windows compatibility (2009-04-03):
- Updated TODO and VERSION (2009-03-25):
- Disabled -fvia-C so the FFI can be used in GHC 6.10
0.12 (2009-03-10):
- Added log1p.
- Added Storable instance (for GHC only)
- removed orphaned toRational/fromRational rules. The RealToFrac module obviates those optimizations.
- Adjusted Real LogFloat instance to throw errors on transfinite values

0.11.2 (2009-03-09):
- Moved log/exp rules from LogFloat into Transfinite (2009-03-09):
- Documentation updates
0.11.1 (2009-03-08):
- Added IArray UArray LogFloat instance (thanks to Felipe Lessa).
0.11 (2009-01-29):
- Moved the RealToFrac class from Data.Number.Transfinite to Data.Number.RealToFrac. This breaks backwards compatibility if you depended directly on that module for the class. If you imported the class from Data.Number.LogFloat then you're still fine.
- Cabal build fail due to missing new module (Fixed in

0.10 (2009-01-29):
- Hugs' Prelude definitions of isInfinite and isNaN for Float and Double are buggy. The new Hugs.RealFloat module provides correct implementations (defaulting to the Prelude definition for non-Hugs compilers).
- The PartialOrd and Transfinite instances for Double and Float have been updated to use these corrected functions.
- Added maxPO and minPO to PartialOrd and added comparingPO to Data.Number.PartialOrd.
- Minor changes to circumvent bugs in Hackage's new version of Haddock. You should be able to see all the documentation now.

0.9.1 (2008-08-30):
- Fixed some PartialOrd stuff and sanitized documentation
- Build fail on GHC 6.10 due to GHC.Prim (Fixed in
0.9.0 (2008-08-30):
- s/toFractional/realToFrac/g.
- Also moved realToFrac and log to Transfinite
- Build fail on GHC 6.10 due to GHC.Prim

0.8.6 (2008-08-17):
- Removed buggy RULES
- Build fail on GHC 6.10 due to -Werror and removal of -fno-warn-orphans
0.8.5 (2008-08-17):
- Gave up and converted from lhs to hs so Hackage docs work
0.8.4 (2008-08-17):
- Broke out Transfinite
0.8.3 (2008-08-16):
- Documentation updates
0.8.2 (2008-08-14):
- Announced release
- Did a bunch of tweaking. Things should be decent now

- Haddockified
- Fixed monomorphism of LogFloat constructors/destructors.
- Added optimization rules.
- Translated from Perl to Haskell at revision 2007.12.20.
- Converted extensive comments to POD format.
- Did a bunch of profiling, optimizing, and debugging.
- Initial version (in Perl) created for hw5 for NLP with Jason Eisner.
comments powered byDisqus