Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
a local clone.
mir.bignum.fp
Note The module doesn't provide full arithmetic API for now.
- struct
Fp(uint size) if (size % ((uint).sizeof * 8) == 0 && (size >= (uint).sizeof * 8)); - Software floating point number.Parameters:
size coefficient size in bits - nothrow this(bool
sign, longexponent, UInt!sizenormalizedCoefficient); - pure nothrow @nogc @safe this(T)(const T
value, boolnormalize= true)
if (isFloatingPoint!T && (T.mant_dig <= size)); - Constructs Fp from hardaware floating point number.Parameters:
T valueHardware floating point number. Special values nan and inf aren't allowed. bool normalizeflag to indicate if the normalization should be performed. Examples:enum h = -33.0 * 2.0 ^^ -10; auto f = Fp!64(h); assert(f.sign); assert(f.exponent == -10 - (64 - 6)); assert(f.coefficient == 33UL << (64 - 6)); assert(cast(double) f == h); // CTFE static assert(cast(double) Fp!64(h) == h); f = Fp!64(-0.0); assert(f.sign); assert(f.exponent == 0); assert(f.coefficient == 0); // subnormals static assert(cast(float) Fp!64(float.min_normal / 2) == float.min_normal / 2); static assert(cast(float) Fp!64(float.min_normal * float.epsilon) == float.min_normal * float.epsilon); // subnormals static assert(cast(double) Fp!64(double.min_normal / 2) == double.min_normal / 2); static assert(cast(double) Fp!64(double.min_normal * double.epsilon) == double.min_normal * double.epsilon); // subnormals static if (real.mant_dig <= 64) { static assert(cast(real) Fp!128(real.min_normal / 2) == real.min_normal / 2); static assert(cast(real) Fp!128(real.min_normal * real.epsilon) == real.min_normal * real.epsilon); } enum d = cast(float) Fp!64(float.min_normal / 2, false); // subnormals static assert(cast(float) Fp!64(float.min_normal / 2, false) == float.min_normal / 2, d.stringof); static assert(cast(float) Fp!64(float.min_normal * float.epsilon, false) == float.min_normal * float.epsilon); // subnormals static assert(cast(double) Fp!64(double.min_normal / 2, false) == double.min_normal / 2); static assert(cast(double) Fp!64(double.min_normal * double.epsilon, false) == double.min_normal * double.epsilon); // subnormals static if (real.mant_dig <= 64) { static assert(cast(real) Fp!64(real.min_normal / 2, false) == real.min_normal / 2); static assert(cast(real) Fp!64(real.min_normal * real.epsilon, false) == real.min_normal * real.epsilon); } import mir.bignum.fixed: UInt; assert(cast(double)Fp!128(+double.infinity) == +double.infinity); assert(cast(double)Fp!128(-double.infinity) == -double.infinity); import mir.math.ieee : signbit; auto r = cast(double)Fp!128(-double.nan); assert(r != r && r.signbit);
- nothrow this(uint isize)(UInt!isize
integer, boolnormalizedInteger= false);
this(ulongvalue); - Examples:
import mir.bignum.fixed: UInt; auto fp = Fp!128(UInt!128.fromHexString("afbbfae3cd0aff2714a1de7022b0029d")); assert(fp.exponent == 0); assert(fp.coefficient == UInt!128.fromHexString("afbbfae3cd0aff2714a1de7022b0029d")); fp = Fp!128(UInt!128.fromHexString("afbbfae3cd0aff2714a1de7022b0029d"), true); assert(fp.exponent == 0); assert(fp.coefficient == UInt!128.fromHexString("afbbfae3cd0aff2714a1de7022b0029d")); fp = Fp!128(UInt!128.fromHexString("ae3cd0aff2714a1de7022b0029d")); assert(fp.exponent == -20); assert(fp.coefficient == UInt!128.fromHexString("ae3cd0aff2714a1de7022b0029d00000")); fp = Fp!128(UInt!128.fromHexString("e7022b0029d")); assert(fp.exponent == -84); assert(fp.coefficient == UInt!128.fromHexString("e7022b0029d000000000000000000000")); fp = Fp!128(UInt!64.fromHexString("e7022b0029d")); assert(fp.exponent == -84); assert(fp.coefficient == UInt!128.fromHexString("e7022b0029d000000000000000000000")); fp = Fp!128(UInt!64.fromHexString("e7022b0029dd0aff"), true); assert(fp.exponent == -64); assert(fp.coefficient == UInt!128.fromHexString("e7022b0029dd0aff0000000000000000")); fp = Fp!128(UInt!64.fromHexString("e7022b0029d")); assert(fp.exponent == -84); assert(fp.coefficient == UInt!128.fromHexString("e7022b0029d000000000000000000000")); fp = Fp!128(UInt!192.fromHexString("ffffffffffffffffffffffffffffffff1000000000000000")); assert(fp.exponent == 64); assert(fp.coefficient == UInt!128.fromHexString("ffffffffffffffffffffffffffffffff")); fp = Fp!128(UInt!192.fromHexString("ffffffffffffffffffffffffffffffff8000000000000000")); assert(fp.exponent == 65); assert(fp.coefficient == UInt!128.fromHexString("80000000000000000000000000000000")); fp = Fp!128(UInt!192.fromHexString("fffffffffffffffffffffffffffffffe8000000000000000")); assert(fp.exponent == 64); assert(fp.coefficient == UInt!128.fromHexString("fffffffffffffffffffffffffffffffe")); fp = Fp!128(UInt!192.fromHexString("fffffffffffffffffffffffffffffffe8000000000000001")); assert(fp.exponent == 64); assert(fp.coefficient == UInt!128.fromHexString("ffffffffffffffffffffffffffffffff"));
- this(long
value); - this(int
value); - this(uint
value); - const @property bool
isNaN() scope; - const @property bool
isInfinity() scope; - const @property bool
isSpecial() scope; - const bool
opEquals(const Fprhs) scope; - nothrow ref Fp
opOpAssign(string op)(Fprhs) scope return
if (op == "*" || op == "/"); - const nothrow Fp!(max(size, rhsSize))
opBinary(string op : "*", uint rhsSize)(Fp!rhsSizerhs); - Examples:
import mir.bignum.fixed: UInt; auto a = Fp!128(0, -13, UInt!128.fromHexString("dfbbfae3cd0aff2714a1de7022b0029d")); auto b = Fp!128(1, 100, UInt!128.fromHexString("e3251bacb112c88b71ad3f85a970a314")); auto fp = a.opBinary!"*"(b); assert(fp.sign); assert(fp.exponent == 100 - 13 + 128); assert(fp.coefficient == UInt!128.fromHexString("c6841dd302415d785373ab6d93712988"));
- const nothrow Fp!(max(size, rhsSize))
opBinary(string op : "/", uint rhsSize)(Fp!rhsSizerhs); - Uses approximate division for now
TODO use full precision division for void when Fp division is ready
- const nothrow T
opCast(T)()
if (is(Unqual!T == bool)); - const nothrow T
opCast(T, bool noSpecial = false, bool noHalf = false)()
if (is(T == float) || is(T == double) || is(T == real)); - Examples:
import mir.bignum.fixed: UInt; auto fp = Fp!128(1, 100, UInt!128.fromHexString("e3251bacb112cb8b71ad3f85a970a314")); assert(cast(double)fp == -0xE3251BACB112C8p+172); fp = Fp!128(1, long.max, UInt!128.init); assert(cast(double)fp == -double.infinity); import mir.math.ieee : signbit; fp = Fp!128(1, long.max, UInt!128(123)); auto r = cast(double)fp; assert(r != r && r.signbit);
Examples:import mir.bignum.fixed: UInt; auto fp = Fp!128(1, 100, UInt!128.fromHexString("e3251bacb112cb8b71ad3f85a970a314")); static if (real.mant_dig == 64) assert(cast(real)fp == -0xe3251bacb112cb8bp+164L);
Examples:import mir.bignum.fixed: UInt; auto fp = Fp!64(1, 100, UInt!64(0xe3251bacb112cb8b)); version (DigitalMars) { // https://issues.dlang.org/show_bug.cgi?id=20963 assert(cast(double)fp == -0xE3251BACB112C8p+108 || cast(double)fp == -0xE3251BACB112D0p+108); } else { assert(cast(double)fp == -0xE3251BACB112C8p+108); }
Examples:import mir.bignum.fixed: UInt; auto fp = Fp!64(1, 100, UInt!64(0xe3251bacb112cb8b)); static if (real.mant_dig == 64) assert(cast(real)fp == -0xe3251bacb112cb8bp+100L);
- const nothrow T
opCast(T : Fp!newSize, bool noSpecial = false, size_t newSize)()
if (newSize != size); - Examples:
import mir.bignum.fixed: UInt; auto fp = cast(Fp!64) Fp!128(UInt!128.fromHexString("afbbfae3cd0aff2784a1de7022b0029d")); assert(fp.exponent == 64); assert(fp.coefficient == UInt!64.fromHexString("afbbfae3cd0aff28")); assert(Fp!128(-double.infinity) * Fp!128(1) == Fp!128(-double.infinity));
- pure nothrow @nogc @trusted Fp!(coefficientizeA + coefficientizeB)
extendedMul(bool noSpecial = false, uint coefficientizeA, uint coefficientizeB)(Fp!coefficientizeAa, Fp!coefficientizeBb); - template
fp_log2(T) if (is(T == float) || is(T == double) || is(T == real)) - Examples:
import mir.math.common: log2, approxEqual; import mir.bignum.fp: fp_log2; double x = 123456789.0e+123; assert(approxEqual(x.Fp!128.fp_log2!double, x.log2));
- T
fp_log2(uint size)(Fp!sizex);
- template
fp_log(T) if (is(T == float) || is(T == double) || is(T == real)) - Examples:
import mir.math.common: log, approxEqual; import mir.bignum.fp: fp_log; double x = 123456789.0e+123; assert(approxEqual(x.Fp!128.fp_log!double, x.log));
- T
fp_log(uint size)(Fp!sizex);
Copyright © 2016-2026 by Ilya Yaroshenko | Page generated by
Ddoc on Wed Apr 8 13:47:03 2026