MyNixOS website logo
Description

Directed rounding for built-in floating types.

rounded-hw: Rounding control for built-in floating-point types

This package provides directed rounding and interval arithmetic for built-in floating-point types (i.e. Float, Double). Unlike rounded, this package does not depend on an external C library.

In addition to Float and Double, LongDouble from long-double package is supported on x86. There is also support for Float128 from float128 package under a package flag.

API overview

Controlling the rounding direction

The type RoundingMode represents the four rounding directions.

The type Rounded (r :: RoundingMode) a is a wrapper for a, with instances honoring the rounding direction given by r.

module Numeric.Rounded.Hardware where

data RoundingMode
  = ToNearest     -- ^ Round to the nearest value (IEEE754 roundTiesToEven)
  | TowardNegInf  -- ^ Round downward (IEEE754 roundTowardNegative)
  | TowardInf     -- ^ Round upward (IEEE754 roundTowardPositive)
  | TowardZero    -- ^ Round toward zero (IEEE754 roundTowardZero)

newtype Rounded (r :: RoundingMode) a = Rounded { getRounded :: a }

instance ... => Num (Rounded r a)
instance ... => Fractional (Rounded r a)
instance ... => Real (Rounded r a)
instance ... => RealFrac (Rounded r a)

Interval arithmetic

This library also provides basic interval types. See Numeric.Rounded.Hardware.Interval and Numeric.Rounded.Hardware.Interval.NonEmpty.

Usage

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE HexFloatLiterals #-}
import Numeric
import Numeric.Rounded.Hardware

main = do
  putStrLn $ showHFloat (1 + 0x1p-100 :: Double) "" -- -> 0x1p0
  putStrLn $ showHFloat (1 + 0x1p-100 :: Rounded TowardInf Double) "" -- -> 0x1.0000000000001p0

Backends

There are several options to control the rounding direction.

  • Pure Haskell (via Rational)
    • Very slow, but does not depend on FFI and therefore can be used on non-native backends.
    • This implementation is always available via a newtype in Numeric.Rounded.Hardware.Backend.ViaRational.
  • C FFI
    • One of the technologies below is used:
      • C99 (fesetround)
      • SSE2 (_mm_setcsr)
      • AVX512 EVEX encoding (_mm_*_round_*)
      • x87 Control Word (for x87 long double)
      • AArch64 FPCR
    • On x86_64, foreign import prim is used to provide faster interval addition/subtraction.

By default, C FFI is used and an appropriate technology is detected. To disable use of C FFI, set pure-hs flag when building.

The name of the backend used can be obtained with Numeric.Rounded.Hardware.Backend.backendName.

>>> backendName (Proxy :: Proxy Double)
"FastFFI+SSE2"
Metadata

Version

0.4.0

Platforms (75)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-darwin
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-darwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows