double-conversion-2.0.2.0/0000755000000000000000000000000013024046773013502 5ustar0000000000000000double-conversion-2.0.2.0/double-conversion.cabal0000644000000000000000000000705013024046773020125 0ustar0000000000000000name: double-conversion version: 2.0.2.0 license: BSD3 license-file: LICENSE homepage: https://github.com/bos/double-conversion bug-reports: https://github.com/bos/double-conversion/issues category: Text author: Bryan O'Sullivan maintainer: Bryan O'Sullivan stability: experimental synopsis: Fast conversion between double precision floating point and text cabal-version: >= 1.8 build-type: Simple description: A library that performs fast, accurate conversion between double precision floating point and text. . This library is implemented as bindings to the C++ @double-conversion@ library written by Florian Loitsch at Google: . . The 'Text' versions of these functions are about 30 times faster than the default 'show' implementation for the 'Double' type. . The 'ByteString' versions are /slower/ than the 'Text' versions; roughly half the speed. (This seems to be due to the cost of allocating 'ByteString' values via @malloc@.) . As a final note, be aware that the @bytestring-show@ package is about 50% slower than simply using 'show'. extra-source-files: README.markdown benchmarks/*.cabal benchmarks/*.hs double-conversion/*.cmake.in double-conversion/AUTHORS double-conversion/CMakeLists.txt double-conversion/COPYING double-conversion/Changelog double-conversion/LICENSE double-conversion/Makefile double-conversion/README double-conversion/SConstruct double-conversion/src/*.cc double-conversion/src/*.h double-conversion/src/CMakeLists.txt double-conversion/src/SConscript double-conversion/test/CMakeLists.txt double-conversion/test/cctest/*.cc double-conversion/test/cctest/*.h double-conversion/test/cctest/CMakeLists.txt double-conversion/test/cctest/SConscript include/*.h tests/*.hs flag developer description: operate in developer mode default: False manual: True library c-sources: cbits/hs-double-conversion.cc double-conversion/src/bignum.cc double-conversion/src/bignum-dtoa.cc double-conversion/src/cached-powers.cc double-conversion/src/diy-fp.cc double-conversion/src/double-conversion.cc double-conversion/src/fast-dtoa.cc double-conversion/src/fixed-dtoa.cc double-conversion/src/strtod.cc if os(windows) if arch(x86_64) extra-libraries: stdc++-6 gcc_s_seh-1 else extra-libraries: stdc++-6 gcc_s_dw2-1 else if os(darwin) extra-libraries: c++ else extra-libraries: stdc++ include-dirs: double-conversion/src include exposed-modules: Data.Double.Conversion.ByteString Data.Double.Conversion.Text other-modules: Data.Double.Conversion.FFI build-depends: base == 4.*, bytestring, ghc-prim, text >= 0.11.0.8 if flag(developer) ghc-options: -Werror ghc-prof-options: -auto-all else cc-options: -DNDEBUG ghc-options: -Wall test-suite tests type: exitcode-stdio-1.0 hs-source-dirs: tests main-is: Properties.hs other-modules: Regressions ghc-options: -Wall build-depends: HUnit, base, bytestring, double-conversion, test-framework, test-framework-hunit, test-framework-quickcheck2, text source-repository head type: git location: https://github.com/bos/double-conversion source-repository head type: mercurial location: https://bitbucket.org/bos/double-conversion double-conversion-2.0.2.0/LICENSE0000644000000000000000000000257113024046773014514 0ustar0000000000000000See double-conversion/LICENSE for the license that applies to the C++ library. Copyright (c) 2011 MailRank, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. double-conversion-2.0.2.0/README.markdown0000644000000000000000000000164613024046773016212 0ustar0000000000000000# Welcome to double-conversion double-conversion is a fast Haskell library for converting between double precision floating point numbers and text strings. It is implemented as a binding to the V8-derived C++ [double-conversion library](https://github.com/floitsch/double-conversion). # Join in! We are happy to receive bug reports, fixes, documentation enhancements, and other improvements. Please report bugs via the [github issue tracker](https://github.com/bos/double-conversion/issues). Master [git repository](https://github.com/bos/double-conversion): * `git clone git://github.com/bos/double-conversion.git` There's also a [Mercurial mirror](https://bitbucket.org/bos/double-conversion): * `hg clone https://bitbucket.org/bos/double-conversion` (You can create and contribute changes using either git or Mercurial.) Authors ------- This library is written and maintained by Bryan O'Sullivan, . double-conversion-2.0.2.0/Setup.lhs0000644000000000000000000000011413024046773015306 0ustar0000000000000000#!/usr/bin/env runhaskell > import Distribution.Simple > main = defaultMain double-conversion-2.0.2.0/benchmarks/0000755000000000000000000000000013024046773015617 5ustar0000000000000000double-conversion-2.0.2.0/benchmarks/Benchmarks.hs0000644000000000000000000000330013024046773020224 0ustar0000000000000000{-# LANGUAGE ForeignFunctionInterface, OverloadedStrings #-} import Criterion.Main import qualified Data.Double.Conversion.ByteString as B import qualified Data.Double.Conversion.Text as T import Foreign.C.Types (CInt(CInt), CDouble(CDouble)) import qualified Data.Text as T import qualified Text.Show.ByteString as BS main = defaultMain [ bgroup "haskell" [ bench "show" $ nf show (pi::Double) , bench "bytestring-show" $ whnf BS.show (pi::Double) , bgroup "text" [ bench "toShortest" $ whnf T.toShortest pi , bench "toExponential" $ whnf (T.toExponential 3) pi , bench "toPrecision" $ whnf (T.toExponential 8) pi , bench "toFixed" $ whnf (T.toFixed 8) pi ] , bgroup "bytestring" [ bench "toShortest" $ whnf B.toShortest pi , bench "toExponential" $ whnf (B.toExponential 3) pi , bench "toPrecision" $ whnf (B.toExponential 8) pi , bench "toFixed" $ whnf (B.toFixed 8) pi ] ] , bgroup "sprintf" [ bench "exact" $ whnf sprintf_exact pi , bench "exponential" $ whnf (sprintf_exponential 3) pi , bench "fixed" $ whnf (sprintf_fixed 8) pi , bench "generic" $ whnf (sprintf_generic 6) pi , bench "generic_default" $ whnf sprintf_generic_default pi ] ] foreign import ccall unsafe sprintf_exact :: CDouble -> () foreign import ccall unsafe sprintf_exponential :: CInt -> CDouble -> () foreign import ccall unsafe sprintf_fixed :: CInt -> CDouble -> () foreign import ccall unsafe sprintf_generic :: CInt -> CDouble -> () foreign import ccall unsafe sprintf_generic_default :: CDouble -> () double-conversion-2.0.2.0/benchmarks/double-conversion-benchmarks.cabal0000644000000000000000000000044513024046773024356 0ustar0000000000000000name: double-conversion-benchmarks version: 0 cabal-version: >= 1.8 build-type: Simple executable bm main-is: Benchmarks.hs c-sources: sprintf.c build-depends: base, bytestring-show, criterion >= 0.5.0.10, double-conversion, text >= 0.11.0.8 double-conversion-2.0.2.0/cbits/0000755000000000000000000000000013024046773014606 5ustar0000000000000000double-conversion-2.0.2.0/cbits/hs-double-conversion.cc0000644000000000000000000000614713024046773021172 0ustar0000000000000000#include "double-conversion.h" #include "hs-double-conversion.h" #include using namespace double_conversion; static const int kToShortestLength = 26; extern "C" int _hs_ToShortestLength(void) { return kToShortestLength; } static const int kToFixedLength = 1 + DoubleToStringConverter::kMaxFixedDigitsBeforePoint + 1 + DoubleToStringConverter::kMaxFixedDigitsAfterPoint; extern "C" int _hs_ToFixedLength(void) { return kToFixedLength; } static const int kToExponentialLength = DoubleToStringConverter::kMaxExponentialDigits + 8; extern "C" int _hs_ToExponentialLength(void) { return kToExponentialLength; } static const int kToPrecisionLength = DoubleToStringConverter::kMaxPrecisionDigits + 7; extern "C" int _hs_ToPrecisionLength(void) { return kToPrecisionLength; } static int copy(uint16_t *buf, const StringBuilder& builder, const char *cbuf) { const int pos = builder.position(); for (int i = 0; i < pos; i++) buf[i] = cbuf[i]; return pos; } static int copy(uint16_t *buf, const char *cbuf, const int len) { for (int i = 0; i < len; i++) buf[i] = cbuf[i]; return len; } static inline const DoubleToStringConverter& defaultConverter(void) { const int flags = DoubleToStringConverter::UNIQUE_ZERO; static DoubleToStringConverter converter(flags, "Infinity", "NaN", 'e', -6, 21, 6, 0); return converter; } extern "C" int _hs_ToShortest(double value, char *buf) { StringBuilder builder(buf, kToShortestLength); return defaultConverter().ToShortest(value, &builder) ? builder.position() : -1; } extern "C" int _hs_Text_ToShortest(double value, uint16_t *buf) { char cbuf[kToShortestLength]; return copy(buf, cbuf, _hs_ToShortest(value, cbuf)); } extern "C" int _hs_ToFixed(double value, char *buf, const int ndigits) { StringBuilder builder(buf, kToFixedLength); return defaultConverter().ToFixed(value, ndigits, &builder) ? builder.position() : -1; } extern "C" int _hs_Text_ToFixed(double value, uint16_t *buf, const int ndigits) { char cbuf[kToFixedLength]; return copy(buf, cbuf, _hs_ToFixed(value, cbuf, ndigits)); } extern "C" int _hs_ToExponential(double value, char *buf, const int ndigits) { StringBuilder builder(buf, kToExponentialLength); return defaultConverter().ToExponential(value, ndigits, &builder) ? builder.position() : -1; } extern "C" int _hs_Text_ToExponential(double value, uint16_t *buf, const int ndigits) { char cbuf[kToExponentialLength]; return copy(buf, cbuf, _hs_ToExponential(value, cbuf, ndigits)); } extern "C" int _hs_ToPrecision(double value, char *buf, const int precision) { StringBuilder builder(buf, kToPrecisionLength); return defaultConverter().ToPrecision(value, precision, &builder) ? builder.position() : -1; } extern "C" int _hs_Text_ToPrecision(double value, uint16_t *buf, const int precision) { char cbuf[kToPrecisionLength]; return copy(buf, cbuf, _hs_ToPrecision(value, cbuf, precision)); } double-conversion-2.0.2.0/Data/0000755000000000000000000000000013024046773014353 5ustar0000000000000000double-conversion-2.0.2.0/Data/Double/0000755000000000000000000000000013024046773015565 5ustar0000000000000000double-conversion-2.0.2.0/Data/Double/Conversion/0000755000000000000000000000000013024046773017712 5ustar0000000000000000double-conversion-2.0.2.0/Data/Double/Conversion/ByteString.hs0000644000000000000000000000545313024046773022347 0ustar0000000000000000-- | -- Module : Data.Double.Conversion.ByteString -- Copyright : (c) 2011 MailRank, Inc. -- -- License : BSD-style -- Maintainer : bos@serpentine.com -- Stability : experimental -- Portability : GHC -- -- Fast, efficient support for converting between double precision -- floating point values and text. -- -- Although about 15 times faster than plain 'show', these functions -- are /slower/ than their 'Text' counterparts, at roughly half the -- speed. (This seems to be due to the cost of allocating -- 'ByteString' values via @malloc@.) module Data.Double.Conversion.ByteString ( toExponential , toFixed , toPrecision , toShortest ) where import Control.Monad (when) import Foreign.ForeignPtr (withForeignPtr) import Data.Double.Conversion.FFI import Data.Word (Word8) import Data.ByteString.Internal (ByteString(..), mallocByteString) import Foreign.C.Types (CDouble, CInt) import Foreign.Ptr (Ptr) import System.IO.Unsafe (unsafePerformIO) -- | Compute a representation in exponential format with the requested -- number of digits after the decimal point. The last emitted digit is -- rounded. If -1 digits are requested, then the shortest exponential -- representation is computed. toExponential :: Int -> Double -> ByteString toExponential ndigits = convert "toExponential" len $ \val mba -> c_ToExponential val mba (fromIntegral ndigits) where len = c_ToExponentialLength {-# NOINLINE len #-} -- | Compute a decimal representation with a fixed number of digits -- after the decimal point. The last emitted digit is rounded. toFixed :: Int -> Double -> ByteString toFixed ndigits = convert "toFixed" len $ \val mba -> c_ToFixed val mba (fromIntegral ndigits) where len = c_ToFixedLength {-# NOINLINE len #-} -- | Compute the shortest string of digits that correctly represent -- the input number. toShortest :: Double -> ByteString toShortest = convert "toShortest" len c_ToShortest where len = c_ToShortestLength {-# NOINLINE len #-} -- | Compute @precision@ leading digits of the given value either in -- exponential or decimal format. The last computed digit is rounded. toPrecision :: Int -> Double -> ByteString toPrecision ndigits = convert "toPrecision" len $ \val mba -> c_ToPrecision val mba (fromIntegral ndigits) where len = c_ToPrecisionLength {-# NOINLINE len #-} convert :: String -> CInt -> (CDouble -> Ptr Word8 -> IO CInt) -> Double -> ByteString convert func len act val = unsafePerformIO $ do fp <- mallocByteString (fromIntegral len) size <- withForeignPtr fp $ act (realToFrac val) when (size == -1) . fail $ "Data.Double.Conversion.ByteString." ++ func ++ ": conversion failed (invalid precision requested)" return $ PS fp 0 (fromIntegral size) double-conversion-2.0.2.0/Data/Double/Conversion/FFI.hs0000644000000000000000000000464113024046773020657 0ustar0000000000000000{-# LANGUAGE CPP, ForeignFunctionInterface, MagicHash, UnliftedFFITypes #-} -- | -- Module : Data.Double.Conversion.FFI -- Copyright : (c) 2011 MailRank, Inc. -- -- License : BSD-style -- Maintainer : bos@serpentine.com -- Stability : experimental -- Portability : GHC -- -- FFI interface support for converting between double precision -- floating point values and text. module Data.Double.Conversion.FFI ( c_Text_ToExponential , c_Text_ToFixed , c_Text_ToPrecision , c_Text_ToShortest , c_ToExponentialLength , c_ToFixedLength , c_ToPrecisionLength , c_ToShortestLength , c_ToExponential , c_ToFixed , c_ToPrecision , c_ToShortest ) where import Data.Word (Word8) #if __GLASGOW_HASKELL__ >= 703 import Foreign.C.Types (CDouble(CDouble), CInt(CInt)) #else import Foreign.C.Types (CDouble, CInt) #endif import Foreign.Ptr (Ptr) import GHC.Prim (MutableByteArray#) foreign import ccall unsafe "hs-double-conversion.h _hs_ToShortestLength" c_ToShortestLength :: CInt foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToShortest" c_Text_ToShortest :: CDouble -> MutableByteArray# s -> IO CInt foreign import ccall unsafe "hs-double-conversion.h _hs_ToShortest" c_ToShortest :: CDouble -> Ptr Word8 -> IO CInt foreign import ccall unsafe "hs-double-conversion.h _hs_ToFixedLength" c_ToFixedLength :: CInt foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToFixed" c_Text_ToFixed :: CDouble -> MutableByteArray# s -> CInt -> IO CInt foreign import ccall unsafe "hs-double-conversion.h _hs_ToFixed" c_ToFixed :: CDouble -> Ptr Word8 -> CInt -> IO CInt foreign import ccall unsafe "hs-double-conversion.h _hs_ToExponentialLength" c_ToExponentialLength :: CInt foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToExponential" c_Text_ToExponential :: CDouble -> MutableByteArray# s -> CInt -> IO CInt foreign import ccall unsafe "hs-double-conversion.h _hs_ToExponential" c_ToExponential :: CDouble -> Ptr Word8 -> CInt -> IO CInt foreign import ccall unsafe "hs-double-conversion.h _hs_ToPrecisionLength" c_ToPrecisionLength :: CInt foreign import ccall unsafe "hs-double-conversion.h _hs_Text_ToPrecision" c_Text_ToPrecision :: CDouble -> MutableByteArray# s -> CInt -> IO CInt foreign import ccall unsafe "hs-double-conversion.h _hs_ToPrecision" c_ToPrecision :: CDouble -> Ptr Word8 -> CInt -> IO CInt double-conversion-2.0.2.0/Data/Double/Conversion/Text.hs0000644000000000000000000000555013024046773021177 0ustar0000000000000000{-# LANGUAGE CPP, MagicHash, Rank2Types #-} -- | -- Module : Data.Double.Conversion.Text -- Copyright : (c) 2011 MailRank, Inc. -- -- License : BSD-style -- Maintainer : bos@serpentine.com -- Stability : experimental -- Portability : GHC -- -- Fast, efficient support for converting between double precision -- floating point values and text. -- -- These functions are about 30 times faster than the default 'show' -- implementation for the 'Double' type. module Data.Double.Conversion.Text ( toExponential , toFixed , toPrecision , toShortest ) where import Control.Monad (when) #if MIN_VERSION_base(4,4,0) import Control.Monad.ST.Unsafe (unsafeIOToST) #else import Control.Monad.ST (unsafeIOToST) #endif import Control.Monad.ST (runST) import Data.Double.Conversion.FFI import Data.Text.Internal (Text(Text)) import Foreign.C.Types (CDouble, CInt) import GHC.Prim (MutableByteArray#) import qualified Data.Text.Array as A -- | Compute a representation in exponential format with the requested -- number of digits after the decimal point. The last emitted digit is -- rounded. If -1 digits are requested, then the shortest exponential -- representation is computed. toExponential :: Int -> Double -> Text toExponential ndigits = convert "toExponential" len $ \val mba -> c_Text_ToExponential val mba (fromIntegral ndigits) where len = c_ToExponentialLength {-# NOINLINE len #-} -- | Compute a decimal representation with a fixed number of digits -- after the decimal point. The last emitted digit is rounded. toFixed :: Int -> Double -> Text toFixed ndigits = convert "toFixed" len $ \val mba -> c_Text_ToFixed val mba (fromIntegral ndigits) where len = c_ToFixedLength {-# NOINLINE len #-} -- | Compute the shortest string of digits that correctly represent -- the input number. toShortest :: Double -> Text toShortest = convert "toShortest" len c_Text_ToShortest where len = c_ToShortestLength {-# NOINLINE len #-} -- | Compute @precision@ leading digits of the given value either in -- exponential or decimal format. The last computed digit is rounded. toPrecision :: Int -> Double -> Text toPrecision ndigits = convert "toPrecision" len $ \val mba -> c_Text_ToPrecision val mba (fromIntegral ndigits) where len = c_ToPrecisionLength {-# NOINLINE len #-} convert :: String -> CInt -> (forall s. CDouble -> MutableByteArray# s -> IO CInt) -> Double -> Text convert func len act val = runST go where go = do buf <- A.new (fromIntegral len) size <- unsafeIOToST $ act (realToFrac val) (A.maBA buf) when (size == -1) . fail $ "Data.Double.Conversion.Text." ++ func ++ ": conversion failed (invalid precision requested)" frozen <- A.unsafeFreeze buf return $ Text frozen 0 (fromIntegral size) double-conversion-2.0.2.0/include/0000755000000000000000000000000013024046773015125 5ustar0000000000000000double-conversion-2.0.2.0/include/hs-double-conversion.h0000644000000000000000000000143613024046773021347 0ustar0000000000000000#ifndef _hs_double_conversion_h #define _hs_double_conversion_h #ifdef __cplusplus extern "C" { #endif #include int _hs_ToShortestLength(void); int _hs_Text_ToShortest(double value, uint16_t *buf); int _hs_ToShortest(double value, char *buf); int _hs_ToFixedLength(void); int _hs_Text_ToFixed(double value, uint16_t *buf, int ndigits); int _hs_ToFixed(double value, char *buf, int ndigits); int _hs_ToExponentialLength(void); int _hs_Text_ToExponential(double value, uint16_t *buf, int ndigits); int _hs_ToExponential(double value, char *buf, int ndigits); int _hs_ToPrecisionLength(void); int _hs_Text_ToPrecision(double value, uint16_t *buf, int ndigits); int _hs_ToPrecision(double value, char *buf, int ndigits); #ifdef __cplusplus } #endif #endif /* _hs_double_conversion_h */ double-conversion-2.0.2.0/tests/0000755000000000000000000000000013024046773014644 5ustar0000000000000000double-conversion-2.0.2.0/tests/Properties.hs0000644000000000000000000000154313024046773017337 0ustar0000000000000000import Test.Framework (Test, defaultMain, testGroup) import Test.Framework.Providers.QuickCheck2 (testProperty) import qualified Data.ByteString.Char8 as B import qualified Data.Double.Conversion.ByteString as B import qualified Data.Double.Conversion.Text as T import qualified Data.Text as T import qualified Regressions shortest :: (Double -> String) -> Double -> Double -> Bool shortest f a b = case read (f ab) of ba | isNaN ba -> isNaN ab | isInfinite ba -> isInfinite ab && signum ba == signum ab | otherwise -> ba == ab where ab = a / b tests :: Test tests = testGroup "Properties" [ testProperty "b_shortest" $ shortest (B.unpack . B.toShortest) , testProperty "t_shortest" $ shortest (T.unpack . T.toShortest) ] main :: IO () main = defaultMain [tests, Regressions.tests] double-conversion-2.0.2.0/tests/Regressions.hs0000644000000000000000000000115113024046773017501 0ustar0000000000000000module Regressions ( tests ) where import Data.Double.Conversion.Text (toShortest) import Test.HUnit (Assertion, assertEqual) import Data.Text (unpack) import Numeric (showFFloat) import qualified Test.Framework as F import qualified Test.Framework.Providers.HUnit as F toShortest_overflow :: Assertion toShortest_overflow = do let val = -2.9658956854023756e-5 assertEqual "rendering a long number doesn't crash" (showFFloat Nothing val "") (unpack (toShortest val)) tests :: F.Test tests = F.testGroup "Regressions" [ F.testCase "toShortest_overflow" toShortest_overflow ]