Skip to main content

Arbitrary-Precision Floating-Point Library  

Latest Version Docs Badge

ARPFloat is an implementation of arbitrary precision floating point data structures and utilities. The library can be used to emulate existing floating point types, such as FP16, and create new floating point types. Floating point types can scale to hundreds of digits, and perform very accurate calculations. In ARPFloat the rounding mode is a part of the type-system, and this defines away a number of problem that show up when using fenv.h.

no_std environments are supported by disabling the std feature. python bindings are supported by enabling the python feature.

Example

  use arpfloat::Float;
  use arpfloat::FP128;

  // Create the number '5' in FP128 format.
  let n = Float::from_f64(5.).cast(FP128);

  // Use Newton-Raphson to find the square root of 5.
  let mut x = n.clone();
  for _ in 0..20 {
      x += (&n / &x)/2;
  }

  println!("fp128: {}", x);
  println!("fp64:  {}", x.as_f64());

The program above will print this output:

fp128: 2.2360679774997896964091736687312763
fp64:  2.23606797749979

The library also provides API that exposes rounding modes, and low-level operations.

    use arpfloat::FP128;
    use arpfloat::RoundingMode::NearestTiesToEven;
    use arpfloat::Float;

    let x = Float::from_u64(FP128, 1<<53);
    let y = Float::from_f64(1000.0).cast(FP128);

    let val = Float::mul_with_rm(&x, &y, NearestTiesToEven);

View the internal representation of numbers:

   use arpfloat::Float;
   use arpfloat::FP16;

   let fp = Float::from_i64(FP16, 15);

   fp.dump(); // Prints FP[+ E=+3 M=11110000000]

   let m = fp.get_mantissa();
    m.dump(); // Prints 11110000000

Control the rounding mode for type conversion:

    use arpfloat::{FP16, FP32, RoundingMode, Float};

    let x = Float::from_u64(FP32, 2649);
    let b = x.cast_with_rm(FP16, RoundingMode::Zero);
    println!("{}", b); // Prints 2648!

Define new float formats and use high-precision transcendental functions:

  use arpfloat::{Float, Semantics};
  // Define a new float format with 120 bits of accuracy, and
  // dynamic range of 2^10.
  let sem = Semantics::new(10, 120);

  let pi = Float::pi(sem);
  let x = Float::exp(&pi);
  println!("e^pi = {}", x); // Prints 23.1406926327792....

Floating point numbers can be converted to Continued Fractions that approximate the value.

 use arpfloat::{Float, FP256, RoundingMode};

 let ln = Float::ln2(FP256);
 println!("ln(2) = {}", ln);
 for i in 1..20 {
   let (p,q) = ln.as_fraction(i);
   println!("{}/{}", p.as_decimal(), q.as_decimal());
 }

The program above will print this output:

  ln(2) = .6931471805599453094172321214581765680755001343602552.....
  0/1
  1/1
  2/3
  7/10
  9/13
  61/88
  192/277
  253/365
  445/642
  1143/1649
  1588/2291
  2731/3940
  ....

The examples directory contains a few programs that demonstrate the use of this library.

Python Bindings

The has python bindings that can be installed with 'pip install -e .'

    >>> from arpfloat import Float, Semantics, FP16, BF16, FP32, fp64, pi

    >>> x = fp64(2.5).cast(FP16)
    >>> y = fp64(1.5).cast(FP16)
    >>> x + y
    4.

    >>> sem = Semantics(10, 10, "NearestTiesToEven")
    >>> sem
    Semantics { exponent: 10, precision: 10, mode: NearestTiesToEven }
    >>> Float(sem, False, 0b1000000001, 0b1100101)
    4.789062

    >>> pi(FP32)
    3.1415927
    >>> pi(FP16)
    3.140625
    >>> pi(BF16)
    3.140625

Arpfloat allows you to experiment with new floating point formats. For example, Nvidia's new FP8 format can be defined as:

    import numpy as np
    from arpfloat import FP32, fp64, Semantics, zero

    # Create two random numpy arrays in the range [0,1)
    A0 = np.random.rand(1000000)
    A1 = np.random.rand(1000000)

    # Calculate the numpy dot product of the two arrays
    print("Using fp32 arithmetic    : ", np.dot(A0, A1))

    # Create the fp8 format (4 exponent bits, 3 mantissa bits + 1 implicit bit)
    FP8 = Semantics(4, 3 + 1, "NearestTiesToEven")

    # Convert the arrays to fp8
    A0 = [fp64(x).cast(FP8) for x in A0]
    A1 = [fp64(x).cast(FP8) for x in A1]

    dot = sum([x.cast(FP32)*y.cast(FP32) for x, y in zip(A0, A1)])
    print("Using fp8/fp32 arithmetic: ", dot)

Resources

There are excellent resources out there, some of which are referenced in the code:

  • Books:
    • Handbook of Floating-Point Arithmetic 2010th by Jean-Michel Muller et al.
    • Elementary Functions: Algorithms and Implementation by Jean-Michel Muller.
    • Modern Computer Arithmetic by Brent and Zimmermann.
  • Papers:
    • An Accurate Elementary Mathematical Library for the IEEE Floating Point Standard, by Gal and Bachels.
    • How to print floating-point numbers accurately by Steele, White.
    • What Every Computer Scientist Should Know About Floating-Point Arithmetic by David Goldberg.
    • Fast Multiple-Precision Evaluation of Elementary Functions by Richard Brent.
    • Fast Trigonometric functions for Arbitrary Precision number by Henrik Vestermark.
  • Other excellent software implementations: APFloat, RYU, libBF, newlib, musl, etc.

License

Licensed under Apache-2.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

arpfloat-0.1.11-cp312-cp312-win_amd64.whl (208.7 kB view details)

Uploaded CPython 3.12Windows x86-64

arpfloat-0.1.11-cp312-cp312-musllinux_1_2_x86_64.whl (305.1 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

arpfloat-0.1.11-cp312-cp312-manylinux_2_31_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.31+ x86-64

File details

Details for the file arpfloat-0.1.11-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: arpfloat-0.1.11-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 208.7 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for arpfloat-0.1.11-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 010c1ba3b09c8059aade5d36750499b787da14b12b31212e69ec2aeb1b3f338a
MD5 db88402bffd1ea3febfb24302f2e3428
BLAKE2b-256 90a999bd06d09f3ddb8bf94894ef0b01bd074599aa8f26c57875898af0d4d44d

See more details on using hashes here.

File details

Details for the file arpfloat-0.1.11-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for arpfloat-0.1.11-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 437be297c0f70096722f5ec4877da230c1c2cf1d63a8039816a91b12a98d9126
MD5 d043edef6352e78f34871d3529332ce4
BLAKE2b-256 9b397db1bb8d8805286c2f3c965f7032102bd70693bd6f97c7450102361fca77

See more details on using hashes here.

File details

Details for the file arpfloat-0.1.11-cp312-cp312-manylinux_2_31_x86_64.whl.

File metadata

File hashes

Hashes for arpfloat-0.1.11-cp312-cp312-manylinux_2_31_x86_64.whl
Algorithm Hash digest
SHA256 a687c684f988aa13928d157defa2c33a692d0358876aa964a1fbf82258a0d9e2
MD5 7c6853a5bd6bfb4950bdc6298d64d192
BLAKE2b-256 c291a31c78a8458b26ccedc70b60ab7f93520939873cf96fd33eb13dd57b729e

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.12

2 files

This release

0.1.11 This release

3 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page