Skip to content

Commit 4813637

Browse files
authored
Rework dec2flot (#412)
* rework decimal to FP conversion * debug * get rid of algorithmR * fixup * fixup
1 parent 3024b5c commit 4813637

15 files changed

Lines changed: 2923 additions & 1660 deletions

File tree

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ void main()
4141
row[3] = 6;
4242
assert(matrix[2, 3] == 6); // D & C index order
4343
44-
import std.stdio;
45-
matrix.writeln; // [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 6]]
44+
import mir.stdio;
45+
matrix.writeln;
46+
// 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]]
4647
}
4748
```
4849

bigint_benchmark/source/app.d

Lines changed: 19 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,26 @@
1-
import mir.bignum.integer: BigInt;
21
import mir.stdio;
3-
import std.bigint: StdBigInt = BigInt;
4-
import gmp.z : GmpBigInt = MpZ, powmod;
52
import std.datetime.stopwatch;
63

74
immutable ps = "E5B5B1EDC8DF0F307C2220151CFCBE31F69B15659A5D6FBA1E50F55A08B341218312D707CFC16ED86A1765F5AEAFA7E6A11C4431038914C76F0F398FE6BE031E289B220D13D9E02226C691D15BC6E1186EA18222D93F52A393BE1DA1A42853512419B5E6E304FD02E962A4C2D0ECDDB8F44AC094FACA8333AE94110A5B10DA539C24A96F08530E7699E3F705165CF14B7F90A2F32ED28D21615F91D7C808AC566D6EEEF6773450AB53542CDAC337C3124530CB16319752267C3422149D41543D8742586BAB578F4E06360745AE0BD8F0E800D1920DC1F3661287367A78967458383A82465C5D966E7299EFCF58BD860185F96655E1F8D300F6B096DFE883CF15";
85
immutable qs = "D9757338E9A6B363F227F3104EDEF6240C0CAF53B7D509F48870553C4A821F460469AE5616301B9CC30FBF4598A176B84284AF3A41D697A34CDC2C8D88A4C4BE82AE8DB5347511FE5B4DD915CA6A728CCFD0444CE38FC7190824059D86A9083C273581EA5AD1D5E3A8D8EC6858F291A5EADA98B0F5FD7C8E8CA6226657B8B7955796B22899B087714E293A86C78D42A7021754A6220F1D0A9588C280DD9AEC376E421D539F30A3053D95C7D70F24B471D14ECF282FA3E0B1CED2C405BA22404F3B75CD961A46097D7C098324FC47281D298734DA0DFCD8AF82E685657C926672727296147867EAEDFDEF89A79DE81FF104CF7D9157EF65A1BC333C98A7FED685";
96
immutable es = ps ~ qs;
107

11-
void stdPowMod(ref StdBigInt base, StdBigInt exponent, StdBigInt modulus)
12-
{
13-
StdBigInt result = 1;
14-
15-
while (exponent != 0)
16-
{
17-
base %= modulus;
18-
if (exponent & 1)
19-
{
20-
result *= base;
21-
result %= modulus;
22-
}
23-
exponent >>= 1;
24-
base *= base;
25-
}
26-
base = result;
27-
}
28-
298
void testStd()
309
{
31-
StdBigInt p = "0x" ~ ps;
32-
StdBigInt q = "0x" ~ qs;
33-
StdBigInt m = p;
10+
import std.bigint;
11+
BigInt p = "0x" ~ ps;
12+
BigInt q = "0x" ~ qs;
13+
BigInt m = p;
3414
m *= q;
35-
StdBigInt e = "0x" ~ es;
36-
StdBigInt b = e;
37-
b.stdPowMod(e, m);
15+
BigInt e = "0x" ~ es;
16+
BigInt b = e;
17+
b = powmod(b, e, m);
3818
debug dout << b << endl;
3919
}
4020

4121
void testMir()
4222
{
23+
import mir.bignum.integer;
4324
auto p = BigInt!64.fromHexString(ps);
4425
auto q = BigInt!64.fromHexString(qs);
4526
BigInt!64 m = p;
@@ -52,14 +33,15 @@ void testMir()
5233

5334
void testGmp()
5435
{
36+
import gmp.z : BigInt = MpZ, powmod;
5537
import std.algorithm.mutation : move;
56-
auto p = GmpBigInt.fromHexString(ps);
57-
auto q = GmpBigInt.fromHexString(qs);
58-
GmpBigInt m = p.move();
38+
auto p = BigInt.fromHexString(ps);
39+
auto q = BigInt.fromHexString(qs);
40+
BigInt m = p.move();
5941
m *= q;
60-
auto e = GmpBigInt.fromHexString(es);
61-
GmpBigInt b = e.dup;
62-
b.powmod(e, m);
42+
auto e = BigInt.fromHexString(es);
43+
BigInt b = e.dup;
44+
b = b.powmod(e, m);
6345
debug dout << b << endl;
6446
}
6547

@@ -76,27 +58,17 @@ void main()
7658
{
7759
import std.system: os;
7860
const res = 10.benchmark!(testStd, testMir, testGmp);
79-
{
80-
const mirRatio = double(res[0].total!"usecs") / res[1].total!"usecs";
81-
dout
61+
const mirRatio = double(res[0].total!"usecs") / res[1].total!"usecs";
62+
const gmpRatio = double(res[0].total!"usecs") / res[2].total!"usecs";
63+
dout
8264
<< "--------------------------------------------" << endl
65+
<< "gmp speedup = " << cast(int)((gmpRatio - 1) * 100_0) / 10.0 << "%" << endl
8366
<< "mir speedup = " << cast(int)((mirRatio - 1) * 100_0) / 10.0 << "%" << endl
8467
<< "std = " << res[0] << endl
8568
<< "mir = " << res[1] << endl
86-
<< " ............... " << size_t.sizeof * 8 << "bit " << os << " ............... " << endl
87-
<< "--------------------------------------------"
88-
<< endl;
89-
}
90-
{
91-
const gmpRatio = double(res[0].total!"usecs") / res[2].total!"usecs";
92-
dout
93-
<< "--------------------------------------------" << endl
94-
<< "gmp speedup = " << cast(int)((gmpRatio - 1) * 100_0) / 10.0 << "%" << endl
95-
<< "std = " << res[0] << endl
9669
<< "gmp = " << res[2] << endl
9770
<< " ............... " << size_t.sizeof * 8 << "bit " << os << " ............... " << endl
9871
<< "--------------------------------------------"
9972
<< endl;
100-
}
10173
}
10274
}

dub.sdl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ copyright "2020 Ilya Yaroshenko, Kaleidic Associates Advisory Limited, Symmetry
66
license "Apache-2.0"
77

88
dependency "mir-core" version=">=1.1.106"
9-
// dependency "silly" version="~>1.1.1"
9+
10+
// versions "TeslAlgoM"
1011

1112
buildType "unittest" {
1213
buildOptions "unittests" "debugMode" "debugInfo"
13-
versions "mir_bignum_test" "mir_bignum_test_llv" "mir_ndslice_test" "mir_test"
14+
versions "mir_bignum_test" "mir_bignum_test_llv" // "mir_ndslice_test" "mir_test"
1415
dflags "-lowmem"
1516
}
1617
buildType "unittest-dip1008" {
@@ -54,7 +55,7 @@ configuration "dips" {
5455
}
5556

5657
configuration "ci-bignum-test" {
57-
versions "mir_bignum_test"
58+
versions "mir_bignum_test" "mir_bignum_test_llv"
5859
}
5960

6061
configuration "ci-core-test" {

source/mir/appender.d

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ struct ScopedBuffer(T, size_t bytes = 4096)
3838
return *cast(inout(T[_bufferLength])*)&_scopeBufferPayload;
3939
}
4040

41-
private T[] prepare(size_t n) @trusted scope
41+
///
42+
T[] prepare(size_t n) @trusted scope
4243
{
4344
import mir.internal.memory: realloc, malloc;
4445
_currentLength += n;

source/mir/bignum/decimal.d

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ private static immutable C[9] zerosImpl(C) = "0.00000.0";
1818
/++
1919
Stack-allocated decimal type.
2020
Params:
21-
maxSize64 = count of 64bit words in coefficient
21+
size64 = count of 64bit words in coefficient
2222
+/
2323
@serdeScoped @serdeProxy!(const(char)[])
24-
struct Decimal(uint maxSize64)
25-
if (maxSize64 && maxSize64 <= ushort.max)
24+
struct Decimal(uint size64)
25+
if (size64 && size64 <= ushort.max)
2626
{
2727
import mir.format: NumericSpec;
2828
import mir.bignum.integer;
@@ -32,7 +32,7 @@ struct Decimal(uint maxSize64)
3232
///
3333
long exponent;
3434
///
35-
BigInt!maxSize64 coefficient;
35+
BigInt!size64 coefficient;
3636

3737
///
3838
DecimalView!size_t view()
@@ -56,11 +56,11 @@ struct Decimal(uint maxSize64)
5656
static if (__traits(compiles, () @nogc { throw new Exception("Can't parse Decimal."); }))
5757
{
5858
import mir.exception: MirException;
59-
throw new MirException("Can't parse Decimal!" ~ maxSize64.stringof ~ " from string `", str , "`");
59+
throw new MirException("Can't parse Decimal!" ~ size64.stringof ~ " from string `", str , "`");
6060
}
6161
else
6262
{
63-
static immutable exception = new Exception("Can't parse Decimal!" ~ maxSize64.stringof ~ ".");
63+
static immutable exception = new Exception("Can't parse Decimal!" ~ size64.stringof ~ ".");
6464
throw exception;
6565
}
6666
}
@@ -71,15 +71,15 @@ struct Decimal(uint maxSize64)
7171
The number is the shortest decimal representation that being converted back would result the same floating-point number.
7272
+/
7373
this(T)(const T x)
74-
if (isFloatingPoint!T && maxSize64 >= 1 + (T.mant_dig >= 64))
74+
if (isFloatingPoint!T && size64 >= 1 + (T.mant_dig >= 64))
7575
{
7676
import mir.bignum.internal.ryu.generic_128: genericBinaryToDecimal;
7777
this = genericBinaryToDecimal(x);
7878
}
7979

8080
///
8181
ref opAssign(uint rhsMaxSize64)(auto ref scope const Decimal!rhsMaxSize64 rhs) return
82-
if (rhsMaxSize64 < maxSize64)
82+
if (rhsMaxSize64 < size64)
8383
{
8484
this.exponent = rhs.exponent;
8585
this.coefficient = rhs.coefficient;
@@ -180,7 +180,7 @@ struct Decimal(uint maxSize64)
180180
scope @trusted pure @nogc nothrow
181181
if (isSomeChar!C)
182182
{
183-
enum optimize = size_t.sizeof == 8 && maxSize64 == 1;
183+
enum optimize = size_t.sizeof == 8 && size64 == 1;
184184
version(LDC)
185185
{
186186
static if (optimize || (allowSpecialValues && allowDExponent && allowStartingPlus && checkEmpty) == false)
@@ -333,7 +333,7 @@ struct Decimal(uint maxSize64)
333333
v = mulu(v, multplier, overflow);
334334
if (overflow)
335335
return false;
336-
v = addu(v, value, overflow);;
336+
v = addu(v, value, overflow);
337337
if (overflow)
338338
return false;
339339
}
@@ -351,7 +351,7 @@ struct Decimal(uint maxSize64)
351351
v = mulu(v, cast(uint)10, overflow);
352352
if (overflow)
353353
return false;
354-
v = addu(v, d, overflow);;
354+
v = addu(v, d, overflow);
355355
if (overflow)
356356
return false;
357357
}
@@ -503,13 +503,13 @@ struct Decimal(uint maxSize64)
503503
}
504504
else
505505
{
506-
BigInt!maxSize64 work = coefficient;
506+
BigInt!size64 work = coefficient;
507507
coefficientLength = work.view.unsigned.toStringImpl(buffer);
508508
}
509509
}
510510
else
511511
{
512-
BigInt!maxSize64 work = coefficient;
512+
BigInt!size64 work = coefficient;
513513
coefficientLength = work.view.unsigned.toStringImpl(buffer);
514514
}
515515

@@ -675,7 +675,7 @@ struct Decimal(uint maxSize64)
675675
if (op == "+" || op == "-")
676676
{
677677
import mir.utility: max;
678-
BigInt!(max(rhsMaxSize64, maxSize64, 256u)) rhsCopy = void;
678+
BigInt!(max(rhsMaxSize64, size64, 256u)) rhsCopy = void;
679679
BigIntView!(const size_t) rhsView;
680680
auto expDiff = cast(sizediff_t) (exponent - rhs.exponent);
681681
if (expDiff >= 0)
@@ -702,13 +702,14 @@ version(mir_bignum_test)
702702
@safe pure nothrow @nogc
703703
unittest
704704
{
705+
import mir.test: should;
705706
import mir.conv: to;
706707
Decimal!256 decimal = void;
707708
DecimalExponentKey key;
708709

709710
assert(decimal.fromStringImpl("3.141592653589793378e-10", key));
710-
assert(cast(double) decimal == 0x1.596bf8ce7631ep-32);
711-
assert(key == DecimalExponentKey.e);
711+
decimal.to!double.should == 0x1.596bf8ce7631ep-32;
712+
key.should == DecimalExponentKey.e;
712713
}
713714

714715
///
@@ -808,6 +809,8 @@ version(mir_bignum_test)
808809
@safe pure nothrow @nogc
809810
unittest
810811
{
812+
import mir.test: should;
813+
811814
import mir.conv: to;
812815
Decimal!3 decimal;
813816
DecimalExponentKey key;
@@ -865,7 +868,7 @@ unittest
865868
assert(decimal.coefficient.length == 0);
866869
assert(decimal.exponent == decimal.exponent.max);
867870
assert(key == DecimalExponentKey.infinity);
868-
assert(cast(double) decimal == -double.infinity);
871+
should(cast(double) decimal) == -double.infinity;
869872

870873
assert(!decimal.fromStringImpl("3.3.4", key));
871874
assert(!decimal.fromStringImpl("3.4.", key));

0 commit comments

Comments
 (0)