Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ void main()
row[3] = 6;
assert(matrix[2, 3] == 6); // D & C index order

import std.stdio;
matrix.writeln; // [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 6]]
import mir.stdio;
matrix.writeln;
// prints [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 6.0]]
}
```

Expand Down
66 changes: 19 additions & 47 deletions bigint_benchmark/source/app.d
Original file line number Diff line number Diff line change
@@ -1,45 +1,26 @@
import mir.bignum.integer: BigInt;
import mir.stdio;
import std.bigint: StdBigInt = BigInt;
import gmp.z : GmpBigInt = MpZ, powmod;
import std.datetime.stopwatch;

immutable ps = "E5B5B1EDC8DF0F307C2220151CFCBE31F69B15659A5D6FBA1E50F55A08B341218312D707CFC16ED86A1765F5AEAFA7E6A11C4431038914C76F0F398FE6BE031E289B220D13D9E02226C691D15BC6E1186EA18222D93F52A393BE1DA1A42853512419B5E6E304FD02E962A4C2D0ECDDB8F44AC094FACA8333AE94110A5B10DA539C24A96F08530E7699E3F705165CF14B7F90A2F32ED28D21615F91D7C808AC566D6EEEF6773450AB53542CDAC337C3124530CB16319752267C3422149D41543D8742586BAB578F4E06360745AE0BD8F0E800D1920DC1F3661287367A78967458383A82465C5D966E7299EFCF58BD860185F96655E1F8D300F6B096DFE883CF15";
immutable qs = "D9757338E9A6B363F227F3104EDEF6240C0CAF53B7D509F48870553C4A821F460469AE5616301B9CC30FBF4598A176B84284AF3A41D697A34CDC2C8D88A4C4BE82AE8DB5347511FE5B4DD915CA6A728CCFD0444CE38FC7190824059D86A9083C273581EA5AD1D5E3A8D8EC6858F291A5EADA98B0F5FD7C8E8CA6226657B8B7955796B22899B087714E293A86C78D42A7021754A6220F1D0A9588C280DD9AEC376E421D539F30A3053D95C7D70F24B471D14ECF282FA3E0B1CED2C405BA22404F3B75CD961A46097D7C098324FC47281D298734DA0DFCD8AF82E685657C926672727296147867EAEDFDEF89A79DE81FF104CF7D9157EF65A1BC333C98A7FED685";
immutable es = ps ~ qs;

void stdPowMod(ref StdBigInt base, StdBigInt exponent, StdBigInt modulus)
{
StdBigInt result = 1;

while (exponent != 0)
{
base %= modulus;
if (exponent & 1)
{
result *= base;
result %= modulus;
}
exponent >>= 1;
base *= base;
}
base = result;
}

void testStd()
{
StdBigInt p = "0x" ~ ps;
StdBigInt q = "0x" ~ qs;
StdBigInt m = p;
import std.bigint;
BigInt p = "0x" ~ ps;
BigInt q = "0x" ~ qs;
BigInt m = p;
m *= q;
StdBigInt e = "0x" ~ es;
StdBigInt b = e;
b.stdPowMod(e, m);
BigInt e = "0x" ~ es;
BigInt b = e;
b = powmod(b, e, m);
debug dout << b << endl;
}

void testMir()
{
import mir.bignum.integer;
auto p = BigInt!64.fromHexString(ps);
auto q = BigInt!64.fromHexString(qs);
BigInt!64 m = p;
Expand All @@ -52,14 +33,15 @@ void testMir()

void testGmp()
{
import gmp.z : BigInt = MpZ, powmod;
import std.algorithm.mutation : move;
auto p = GmpBigInt.fromHexString(ps);
auto q = GmpBigInt.fromHexString(qs);
GmpBigInt m = p.move();
auto p = BigInt.fromHexString(ps);
auto q = BigInt.fromHexString(qs);
BigInt m = p.move();
m *= q;
auto e = GmpBigInt.fromHexString(es);
GmpBigInt b = e.dup;
b.powmod(e, m);
auto e = BigInt.fromHexString(es);
BigInt b = e.dup;
b = b.powmod(e, m);
debug dout << b << endl;
}

Expand All @@ -76,27 +58,17 @@ void main()
{
import std.system: os;
const res = 10.benchmark!(testStd, testMir, testGmp);
{
const mirRatio = double(res[0].total!"usecs") / res[1].total!"usecs";
dout
const mirRatio = double(res[0].total!"usecs") / res[1].total!"usecs";
const gmpRatio = double(res[0].total!"usecs") / res[2].total!"usecs";
dout
<< "--------------------------------------------" << endl
<< "gmp speedup = " << cast(int)((gmpRatio - 1) * 100_0) / 10.0 << "%" << endl
<< "mir speedup = " << cast(int)((mirRatio - 1) * 100_0) / 10.0 << "%" << endl
<< "std = " << res[0] << endl
<< "mir = " << res[1] << endl
<< " ............... " << size_t.sizeof * 8 << "bit " << os << " ............... " << endl
<< "--------------------------------------------"
<< endl;
}
{
const gmpRatio = double(res[0].total!"usecs") / res[2].total!"usecs";
dout
<< "--------------------------------------------" << endl
<< "gmp speedup = " << cast(int)((gmpRatio - 1) * 100_0) / 10.0 << "%" << endl
<< "std = " << res[0] << endl
<< "gmp = " << res[2] << endl
<< " ............... " << size_t.sizeof * 8 << "bit " << os << " ............... " << endl
<< "--------------------------------------------"
<< endl;
}
}
}
7 changes: 4 additions & 3 deletions dub.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ copyright "2020 Ilya Yaroshenko, Kaleidic Associates Advisory Limited, Symmetry
license "Apache-2.0"

dependency "mir-core" version=">=1.1.106"
// dependency "silly" version="~>1.1.1"

// versions "TeslAlgoM"

buildType "unittest" {
buildOptions "unittests" "debugMode" "debugInfo"
versions "mir_bignum_test" "mir_bignum_test_llv" "mir_ndslice_test" "mir_test"
versions "mir_bignum_test" "mir_bignum_test_llv" // "mir_ndslice_test" "mir_test"
dflags "-lowmem"
}
buildType "unittest-dip1008" {
Expand Down Expand Up @@ -54,7 +55,7 @@ configuration "dips" {
}

configuration "ci-bignum-test" {
versions "mir_bignum_test"
versions "mir_bignum_test" "mir_bignum_test_llv"
}

configuration "ci-core-test" {
Expand Down
3 changes: 2 additions & 1 deletion source/mir/appender.d
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ struct ScopedBuffer(T, size_t bytes = 4096)
return *cast(inout(T[_bufferLength])*)&_scopeBufferPayload;
}

private T[] prepare(size_t n) @trusted scope
///
T[] prepare(size_t n) @trusted scope
{
import mir.internal.memory: realloc, malloc;
_currentLength += n;
Expand Down
37 changes: 20 additions & 17 deletions source/mir/bignum/decimal.d
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ private static immutable C[9] zerosImpl(C) = "0.00000.0";
/++
Stack-allocated decimal type.
Params:
maxSize64 = count of 64bit words in coefficient
size64 = count of 64bit words in coefficient
+/
@serdeScoped @serdeProxy!(const(char)[])
struct Decimal(uint maxSize64)
if (maxSize64 && maxSize64 <= ushort.max)
struct Decimal(uint size64)
if (size64 && size64 <= ushort.max)
{
import mir.format: NumericSpec;
import mir.bignum.integer;
Expand All @@ -32,7 +32,7 @@ struct Decimal(uint maxSize64)
///
long exponent;
///
BigInt!maxSize64 coefficient;
BigInt!size64 coefficient;

///
DecimalView!size_t view()
Expand All @@ -56,11 +56,11 @@ struct Decimal(uint maxSize64)
static if (__traits(compiles, () @nogc { throw new Exception("Can't parse Decimal."); }))
{
import mir.exception: MirException;
throw new MirException("Can't parse Decimal!" ~ maxSize64.stringof ~ " from string `", str , "`");
throw new MirException("Can't parse Decimal!" ~ size64.stringof ~ " from string `", str , "`");
}
else
{
static immutable exception = new Exception("Can't parse Decimal!" ~ maxSize64.stringof ~ ".");
static immutable exception = new Exception("Can't parse Decimal!" ~ size64.stringof ~ ".");
throw exception;
}
}
Expand All @@ -71,15 +71,15 @@ struct Decimal(uint maxSize64)
The number is the shortest decimal representation that being converted back would result the same floating-point number.
+/
this(T)(const T x)
if (isFloatingPoint!T && maxSize64 >= 1 + (T.mant_dig >= 64))
if (isFloatingPoint!T && size64 >= 1 + (T.mant_dig >= 64))
{
import mir.bignum.internal.ryu.generic_128: genericBinaryToDecimal;
this = genericBinaryToDecimal(x);
}

///
ref opAssign(uint rhsMaxSize64)(auto ref scope const Decimal!rhsMaxSize64 rhs) return
if (rhsMaxSize64 < maxSize64)
if (rhsMaxSize64 < size64)
{
this.exponent = rhs.exponent;
this.coefficient = rhs.coefficient;
Expand Down Expand Up @@ -180,7 +180,7 @@ struct Decimal(uint maxSize64)
scope @trusted pure @nogc nothrow
if (isSomeChar!C)
{
enum optimize = size_t.sizeof == 8 && maxSize64 == 1;
enum optimize = size_t.sizeof == 8 && size64 == 1;
version(LDC)
{
static if (optimize || (allowSpecialValues && allowDExponent && allowStartingPlus && checkEmpty) == false)
Expand Down Expand Up @@ -333,7 +333,7 @@ struct Decimal(uint maxSize64)
v = mulu(v, multplier, overflow);
if (overflow)
return false;
v = addu(v, value, overflow);;
v = addu(v, value, overflow);
if (overflow)
return false;
}
Expand All @@ -351,7 +351,7 @@ struct Decimal(uint maxSize64)
v = mulu(v, cast(uint)10, overflow);
if (overflow)
return false;
v = addu(v, d, overflow);;
v = addu(v, d, overflow);
if (overflow)
return false;
}
Expand Down Expand Up @@ -503,13 +503,13 @@ struct Decimal(uint maxSize64)
}
else
{
BigInt!maxSize64 work = coefficient;
BigInt!size64 work = coefficient;
coefficientLength = work.view.unsigned.toStringImpl(buffer);
}
}
else
{
BigInt!maxSize64 work = coefficient;
BigInt!size64 work = coefficient;
coefficientLength = work.view.unsigned.toStringImpl(buffer);
}

Expand Down Expand Up @@ -675,7 +675,7 @@ struct Decimal(uint maxSize64)
if (op == "+" || op == "-")
{
import mir.utility: max;
BigInt!(max(rhsMaxSize64, maxSize64, 256u)) rhsCopy = void;
BigInt!(max(rhsMaxSize64, size64, 256u)) rhsCopy = void;
BigIntView!(const size_t) rhsView;
auto expDiff = cast(sizediff_t) (exponent - rhs.exponent);
if (expDiff >= 0)
Expand All @@ -702,13 +702,14 @@ version(mir_bignum_test)
@safe pure nothrow @nogc
unittest
{
import mir.test: should;
import mir.conv: to;
Decimal!256 decimal = void;
DecimalExponentKey key;

assert(decimal.fromStringImpl("3.141592653589793378e-10", key));
assert(cast(double) decimal == 0x1.596bf8ce7631ep-32);
assert(key == DecimalExponentKey.e);
decimal.to!double.should == 0x1.596bf8ce7631ep-32;
key.should == DecimalExponentKey.e;
}

///
Expand Down Expand Up @@ -808,6 +809,8 @@ version(mir_bignum_test)
@safe pure nothrow @nogc
unittest
{
import mir.test: should;

import mir.conv: to;
Decimal!3 decimal;
DecimalExponentKey key;
Expand Down Expand Up @@ -865,7 +868,7 @@ unittest
assert(decimal.coefficient.length == 0);
assert(decimal.exponent == decimal.exponent.max);
assert(key == DecimalExponentKey.infinity);
assert(cast(double) decimal == -double.infinity);
should(cast(double) decimal) == -double.infinity;

assert(!decimal.fromStringImpl("3.3.4", key));
assert(!decimal.fromStringImpl("3.4.", key));
Expand Down
Loading