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.decimal
Stack-allocated decimal type.
Note The module doesn't provide full arithmetic API for now.
- public import mir.parse :
DecimalExponentKey; - struct
Decimal(uint size64) if (size64 && (size64 <= (ushort).max)); - Stack-allocated decimal type.Parameters:
size64 count of 64bit words in coefficient Examples:import mir.test: should; import mir.conv: to; Decimal!128 decimal = void; DecimalExponentKey key; assert(decimal.fromStringImpl("3.141592653589793378e-10", key)); decimal.opCast!double.should == 0x1.596bf8ce7631ep-32; key.should == DecimalExponentKey.e;
Examples:import mir.conv: to; Decimal!3 decimal; DecimalExponentKey key; assert(decimal.fromStringImpl("0", key)); assert(key == DecimalExponentKey.none); assert(decimal.exponent == 0); assert(decimal.coefficient.length == 0); assert(!decimal.coefficient.sign); assert(cast(double) decimal.coefficient == 0); assert(decimal.fromStringImpl("-0.0", key)); assert(key == DecimalExponentKey.dot); assert(decimal.exponent == -1); assert(decimal.coefficient.length == 0); assert(decimal.coefficient.sign); assert(cast(double) decimal.coefficient == 0); assert(decimal.fromStringImpl("0e0", key)); assert(key == DecimalExponentKey.e); assert(decimal.exponent == 0); assert(decimal.coefficient.length == 0); assert(!decimal.coefficient.sign); assert(cast(double) decimal.coefficient == 0);
Examples:auto a = Decimal!1("777.7"); auto b = Decimal!1("777"); import mir.format; assert(stringBuf() << cast(double)a - cast(double)b << getData == "0.7000000000000455"); a -= b; assert(stringBuf() << a << getData == "0.7"); a = Decimal!1("-777.7"); b = Decimal!1("777"); a += b; assert(stringBuf() << a << getData == "-0.7"); a = Decimal!1("777.7"); b = Decimal!1("-777"); a += b; assert(stringBuf() << a << getData == "0.7"); a = Decimal!1("777"); b = Decimal!1("777.7"); a -= b; assert(stringBuf() << a << getData == "-0.7");
Examples:Check @nogc toString implimport mir.format: stringBuf; auto str = "5.28238923728e-876543210"; auto decimal = Decimal!1(str); auto buffer = stringBuf; buffer << decimal; assert(buffer.data == str);
Examples:Decimal!4 i = "-0"; assert(i.view.coefficient.coefficients.length == 0); assert(i.coefficient.view.unsigned.coefficients.length == 0); assert(i.coefficient.view == 0L); assert(cast(long) i.coefficient == 0); assert(i.coefficient.sign);
Examples:auto str = "-3.4010447314490204552169750449563978034784726557588085989975288830070948234680e-13245"; auto decimal = Decimal!4(str); assert(decimal.toString == str, decimal.toString); decimal = Decimal!4.init; assert(decimal.toString == "0.0");
Examples:import mir.test: should; import mir.conv: to; Decimal!3 decimal; DecimalExponentKey key; // Check precise percentate parsing assert(decimal.fromStringImpl("71.7", key, -2)); key.should == DecimalExponentKey.dot; // The result is exact value instead of 0.7170000000000001 = 71.7 / 100 (cast(double) decimal).should == 0.717; assert(decimal.fromStringImpl("+0.334e-5"w, key)); key.should == DecimalExponentKey.e; (cast(double) decimal).should == 0.334e-5; assert(decimal.fromStringImpl("100_000_000"w, key)); key.should == DecimalExponentKey.none; (cast(double) decimal).should == 1e8; assert(decimal.fromStringImpl("-334D-5"d, key)); key.should == DecimalExponentKey.D; (cast(double) decimal).should == -334e-5; assert(decimal.fromStringImpl("2482734692817364218734682973648217364981273648923423", key)); key.should == DecimalExponentKey.none; (cast(double) decimal).should == 2482734692817364218734682973648217364981273648923423.0; assert(decimal.fromStringImpl(".023", key)); key.should == DecimalExponentKey.dot; (cast(double) decimal).should == .023; assert(decimal.fromStringImpl("0E100", key)); key.should == DecimalExponentKey.E; (cast(double) decimal).should == 0; foreach (str; ["-nan", "-NaN", "-NAN"]) { assert(decimal.fromStringImpl(str, key)); assert(decimal.coefficient.length > 0); assert(decimal.exponent == decimal.exponent.max); assert(decimal.coefficient.sign); key.should == DecimalExponentKey.nan; auto nan = cast(double) decimal; (cast(double) decimal).should == double.nan; } foreach (str; ["inf", "Inf", "INF"]) { assert(decimal.fromStringImpl(str, key)); assert(decimal.coefficient.length == 0); assert(decimal.exponent == decimal.exponent.max); assert(key == DecimalExponentKey.infinity); (cast(double) decimal).should == double.infinity; } assert(decimal.fromStringImpl("-inf", key)); assert(decimal.coefficient.length == 0); assert(decimal.exponent == decimal.exponent.max); assert(key == DecimalExponentKey.infinity); should(cast(double) decimal) == -double.infinity; assert(!decimal.fromStringImpl("3.3.4", key)); assert(!decimal.fromStringImpl("3.4.", key)); assert(decimal.fromStringImpl("4.", key)); assert(!decimal.fromStringImpl(".", key)); assert(decimal.fromStringImpl("0.", key)); assert(decimal.fromStringImpl("00", key)); assert(!decimal.fromStringImpl("0d", key));
Examples:import mir.math.constant: PI; Decimal!2 decimal = "3.141592653589793378e-40"; // constructor assert(cast(double) decimal == double(PI) / 1e40);
Examples:// float and double can be used to construct Decimal of any length auto decimal64 = Decimal!1(-1.235e-7); assert(decimal64.exponent == -10); assert(decimal64.coefficient == -1235); // real number may need Decimal at least length of 2 auto decimal128 = Decimal!2(-1.235e-7L); assert(decimal128.exponent == -10); assert(decimal128.coefficient == -1235); decimal128 = Decimal!2(1234e3f); assert(decimal128.exponent == 3); assert(decimal128.coefficient == 1234);
Examples:Decimal!3 decimal; DecimalExponentKey key; assert(decimal.fromStringWithThousandsSeparatorImpl("12,345.678", ',', '.', key)); assert(cast(double) decimal == 12345.678); assert(key == DecimalExponentKey.dot); assert(decimal.fromStringWithThousandsSeparatorImpl("12,345,678", ',', '.', key, -3)); assert(cast(double) decimal == 12345.678); assert(key == DecimalExponentKey.none); assert(decimal.fromStringWithThousandsSeparatorImpl("021 345,678", ' ', ',', key)); assert(cast(double) decimal == 21345.678); assert(key == DecimalExponentKey.dot);
- long
exponent; - BigInt!size64
coefficient; - const void
toString(C = char, W)(ref scope Ww, NumericSpecspec= NumericSpec.init) scope
if (isSomeChar!C && isMutable!C); - DecimalView!size_t
view() return scope;
const DecimalView!(const(size_t))view() return scope; - pure @nogc @safe this(C)(scope const(C)[]
str, intexponentShift= 0)
if (isSomeChar!C); - this(T)(const T
x)
if (isFloatingPoint!T && (size64 >= 1 + (T.mant_dig >= 64))); - Constructs Decimal from the floating point number using the Ryu algorithm.The number is the shortest decimal representation that being converted back would result the same floating-point number.
- ref auto
opAssign(uint rhsMaxSize64)(auto ref scope const Decimal!rhsMaxSize64rhs) return
if (rhsMaxSize64 < size64); - @trusted bool
fromStringWithThousandsSeparatorImpl(C, bool allowSpecialValues = true, bool allowStartingPlus = true, bool allowLeadingZeros = true)(scope const(C)[]str, const CthousandsSeparator, const CfractionSeparator, out DecimalExponentKeykey, intexponentShift= 0)
if (isSomeChar!C); - Handle thousand separators for non exponential numbers.Returns:false in case of overflow or incorrect string.
- pure nothrow @nogc @trusted bool
fromStringImpl(C, bool allowSpecialValues = true, bool allowDotOnBounds = true, bool allowDExponent = true, bool allowStartingPlus = true, bool allowUnderscores = true, bool allowLeadingZeros = true, bool allowExponent = true, bool checkEmpty = true)(scope const(C)[]str, out DecimalExponentKeykey, intexponentShift= 0) scope
if (isSomeChar!C); - Returns:false in case of overflow or incorrect string.
- const pure nothrow @safe immutable(C)[]
toString(C = char)(NumericSpecspec= NumericSpec.init) scope
if (isSomeChar!C && isMutable!C); - const T
opCast(T, bool wordNormalized = true)() scope
if (isFloatingPoint!T && isMutable!T); - Mir parsing supports up-to quadruple precision. The conversion error is 0 ULP for normal numbers. Subnormal numbers with an exponent greater than or equal to -512 have upper error bound equal to 1 ULP.
- const @property bool
isNaN() scope; - const @property bool
isInfinity() scope; - const @property bool
isSpecial() scope; - pure ref @trusted auto
opOpAssign(string op, size_t rhsMaxSize64)(const ref Decimal!rhsMaxSize64rhs) return
if (op == "+" || op == "-");
Copyright © 2016-2026 by Ilya Yaroshenko | Page generated by
Ddoc on Wed Apr 8 13:47:03 2026