    -- | Bindings to the C math library.
    --
    -- Follows the naming scheme of the C functions when feasible.
    module Futhark.Util.CMath
      ( roundFloat,
        ceilFloat,
        floorFloat,
        roundDouble,
        ceilDouble,
        floorDouble,
        nextafterf,
        nextafter,
        lgamma,
        lgammaf,
        tgamma,
        tgammaf,
        erf,
        erff,
        erfc,
        erfcf,
        cbrt,
        cbrtf,
        hypot,
        hypotf,
        ldexp,
        ldexpf,
        copysign,
        copysignf,
      )
    where

    import Foreign.C.Types (CInt (..))

    foreign import ccall "nearbyint" c_nearbyint :: Double -> Double

    foreign import ccall "nearbyintf" c_nearbyintf :: Float -> Float

    foreign import ccall "ceil" c_ceil :: Double -> Double

    foreign import ccall "ceilf" c_ceilf :: Float -> Float

    foreign import ccall "floor" c_floor :: Double -> Double

    foreign import ccall "floorf" c_floorf :: Float -> Float

    -- | Round a single-precision floating point number correctly.
    roundFloat :: Float -> Float
    roundFloat :: Float -> Float
    roundFloat = Float -> Float
    c_nearbyintf

    -- | Round a single-precision floating point number upwards correctly.
    ceilFloat :: Float -> Float
    ceilFloat :: Float -> Float
    ceilFloat = Float -> Float
    c_ceilf

    -- | Round a single-precision floating point number downwards correctly.
    floorFloat :: Float -> Float
    floorFloat :: Float -> Float
    floorFloat = Float -> Float
    c_floorf

    -- | Round a double-precision floating point number correctly.
    roundDouble :: Double -> Double
    roundDouble :: Double -> Double
    roundDouble = Double -> Double
    c_nearbyint

    -- | Round a double-precision floating point number upwards correctly.
    ceilDouble :: Double -> Double
    ceilDouble :: Double -> Double
    ceilDouble = Double -> Double
    c_ceil

    -- | Round a double-precision floating point number downwards correctly.
    floorDouble :: Double -> Double
    floorDouble :: Double -> Double
    floorDouble = Double -> Double
    c_floor

    foreign import ccall "nextafter" c_nextafter :: Double -> Double -> Double

    foreign import ccall "nextafterf" c_nextafterf :: Float -> Float -> Float

    -- | The next representable single-precision floating-point value in
    -- the given direction.
    nextafterf :: Float -> Float -> Float
    nextafterf :: Float -> Float -> Float
    nextafterf = Float -> Float -> Float
    c_nextafterf

    -- | The next representable double-precision floating-point value in
    -- the given direction.
    nextafter :: Double -> Double -> Double
    nextafter :: Double -> Double -> Double
    nextafter = Double -> Double -> Double
    c_nextafter

    foreign import ccall "lgamma" c_lgamma :: Double -> Double

    foreign import ccall "lgammaf" c_lgammaf :: Float -> Float

    foreign import ccall "tgamma" c_tgamma :: Double -> Double

    foreign import ccall "tgammaf" c_tgammaf :: Float -> Float

    -- | The system-level @lgamma()@ function.
    lgamma :: Double -> Double
    lgamma :: Double -> Double
    lgamma = Double -> Double
    c_lgamma

    -- | The system-level @lgammaf()@ function.
    lgammaf :: Float -> Float
    lgammaf :: Float -> Float
    lgammaf = Float -> Float
    c_lgammaf

    -- | The system-level @tgamma()@ function.
    tgamma :: Double -> Double
    tgamma :: Double -> Double
    tgamma = Double -> Double
    c_tgamma

    -- | The system-level @tgammaf()@ function.
    tgammaf :: Float -> Float
    tgammaf :: Float -> Float
    tgammaf = Float -> Float
    c_tgammaf

    foreign import ccall "hypot" c_hypot :: Double -> Double -> Double

    foreign import ccall "hypotf" c_hypotf :: Float -> Float -> Float

    -- | The system-level @hypot@ function.
    hypot :: Double -> Double -> Double
    hypot :: Double -> Double -> Double
    hypot = Double -> Double -> Double
    c_hypot

    -- | The system-level @hypotf@ function.
    hypotf :: Float -> Float -> Float
    hypotf :: Float -> Float -> Float
    hypotf = Float -> Float -> Float
    c_hypotf

    foreign import ccall "erf" c_erf :: Double -> Double

    foreign import ccall "erff" c_erff :: Float -> Float

    foreign import ccall "erfc" c_erfc :: Double -> Double

    foreign import ccall "erfcf" c_erfcf :: Float -> Float

    -- | The system-level @erf()@ function.
    erf :: Double -> Double
    erf :: Double -> Double
    erf = Double -> Double
    c_erf

    -- | The system-level @erff()@ function.
    erff :: Float -> Float
    erff :: Float -> Float
    erff = Float -> Float
    c_erff

    -- | The system-level @erfc()@ function.
    erfc :: Double -> Double
    erfc :: Double -> Double
    erfc = Double -> Double
    c_erfc

    -- | The system-level @erfcf()@ function.
    erfcf :: Float -> Float
    erfcf :: Float -> Float
    erfcf = Float -> Float
    c_erfcf

    foreign import ccall "cbrt" c_cbrt :: Double -> Double

    foreign import ccall "cbrtf" c_cbrtf :: Float -> Float

    -- | The system-level @cbrt@ function.
    cbrt :: Double -> Double
    cbrt :: Double -> Double
    cbrt = Double -> Double
    c_cbrt

    -- | The system-level @cbrtf@ function.
    cbrtf :: Float -> Float
    cbrtf :: Float -> Float
    cbrtf = Float -> Float
    c_cbrtf

    foreign import ccall "ldexp" c_ldexp :: Double -> CInt -> Double

    foreign import ccall "ldexpf" c_ldexpf :: Float -> CInt -> Float

    -- | The system-level @ldexp@ function.
    ldexp :: Double -> CInt -> Double
    ldexp :: Double -> CInt -> Double
    ldexp = Double -> CInt -> Double
    c_ldexp

    -- | The system-level @ldexpf@ function.
    ldexpf :: Float -> CInt -> Float
    ldexpf :: Float -> CInt -> Float
    ldexpf = Float -> CInt -> Float
    c_ldexpf

    foreign import ccall "copysign" c_copysign :: Double -> Double -> Double

    foreign import ccall "copysignf" c_copysignf :: Float -> Float -> Float

    -- | The system-level @copysign@ function.
    copysign :: Double -> Double -> Double
    copysign :: Double -> Double -> Double
    copysign = Double -> Double -> Double
    c_copysign

    -- | The system-level @copysignf@ function.
    copysignf :: Float -> Float -> Float
    copysignf :: Float -> Float -> Float
    copysignf = Float -> Float -> Float
    c_copysignf