Skip to content

Commit 9a61cd6

Browse files
committed
fixup biginteger parsing
1 parent 9c4a9e7 commit 9a61cd6

3 files changed

Lines changed: 45 additions & 31 deletions

File tree

source/mir/bignum/integer.d

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -265,10 +265,10 @@ struct BigInt(uint size64)
265265
///
266266
BigInt copy() @property
267267
{
268-
BigInt ret;
268+
BigInt ret = void;
269269
ret.sign = sign;
270270
ret.length = length;
271-
ret.data = data;
271+
ret.data[0 .. length] = data[0 .. length];
272272
return ret;
273273
}
274274

@@ -762,7 +762,7 @@ struct BigInt(uint size64)
762762
static BigInt fromHexString(bool allowUnderscores = false)(scope const(char)[] str)
763763
@trusted pure
764764
{
765-
BigInt ret;
765+
BigInt ret = void;
766766
if (ret.fromHexStringImpl!(char, allowUnderscores)(str))
767767
return ret;
768768
version(D_Exceptions)
@@ -779,11 +779,8 @@ struct BigInt(uint size64)
779779
{
780780
auto work = BigIntView!size_t(data);
781781
auto ret = work.fromHexStringImpl!(C, allowUnderscores)(str);
782-
if (ret)
783-
{
784-
length = cast(uint)work.unsigned.coefficients.length;
785-
sign = work.sign;
786-
}
782+
length = cast(uint)work.unsigned.coefficients.length;
783+
sign = work.sign;
787784
return ret;
788785
}
789786

@@ -792,7 +789,7 @@ struct BigInt(uint size64)
792789
static BigInt fromBinaryString(bool allowUnderscores = false)(scope const(char)[] str)
793790
@trusted pure
794791
{
795-
BigInt ret;
792+
BigInt ret = void;
796793
if (ret.fromBinaryStringImpl!(char, allowUnderscores)(str))
797794
return ret;
798795
version(D_Exceptions)
@@ -817,11 +814,8 @@ struct BigInt(uint size64)
817814
{
818815
auto work = BigIntView!size_t(data);
819816
auto ret = work.fromBinaryStringImpl!(C, allowUnderscores)(str);
820-
if (ret)
821-
{
822-
length = cast(uint)work.unsigned.coefficients.length;
823-
sign = work.sign;
824-
}
817+
length = cast(uint)work.unsigned.coefficients.length;
818+
sign = work.sign;
825819
return ret;
826820
}
827821

@@ -1065,6 +1059,7 @@ version(mir_bignum_test) @safe pure @nogc unittest
10651059
version(mir_bignum_test)
10661060
unittest
10671061
{
1062+
import mir.test;
10681063
import mir.bignum.fixed;
10691064
import mir.bignum.low_level_view;
10701065

@@ -1073,18 +1068,22 @@ unittest
10731068
auto b = UInt!128.fromHexString("f79a222050aaeaaa417fa25a2ac93291");
10741069

10751070
// ca3d7e25aebe687b 168dcef32d0bb2f0
1076-
import mir.format;
1077-
assert((a %= b) == BigInt!4.fromHexString("bf4c87424431d21563f23b1fc00d75ac"));
1071+
auto c = BigInt!4.fromHexString("bf4c87424431d21563f23b1fc00d75ac");
1072+
a %= b;
1073+
a.should == c;
10781074
a = BigInt!4.fromHexString("c39b18a9f06fd8e962d99935cea0707f79a222050aaeaaaed17feb7aa76999d7");
10791075
a /= b;
1080-
assert(a == BigInt!4.fromHexString("ca3d7e25aebe687b7cc1b250b44690fb"), a.data.text);
1076+
assert(a == BigInt!4.fromHexString("ca3d7e25aebe687b7cc1b250b44690fb"));
10811077
}
10821078

10831079
{
10841080
auto a = BigInt!4.fromHexString("7fff000080000000000000000000");
10851081
auto b = UInt!128.fromHexString("80000000000000000001");
10861082

1087-
assert((a /= b) == BigInt!4.fromHexString("fffe0000"));
1083+
auto c = BigInt!4.fromHexString("fffe0000");
1084+
a /= b;
1085+
a.should == c;
1086+
10881087
a = BigInt!4.fromHexString("7fff000080000000000000000000");
10891088
assert((a %= b) == BigInt!4.fromHexString("7fffffffffff00020000"));
10901089
}

source/mir/bignum/internal/kernel.d

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ unittest
183183
// Test division by a single-digit divisor here.
184184
auto dividend = BigUIntView!uint.fromHexString("5");
185185
auto divisor = BigUIntView!uint.fromHexString("5");
186-
auto quotient = BigUIntView!uint.fromHexString("0");
186+
auto quotient = BigUIntView!uint([0u]);
187187
// auto remainder = BigUIntView!uint.fromHexString("0");
188188

189189
divMod(dividend, divisor, quotient);
@@ -194,7 +194,7 @@ unittest
194194
// Test division by a single-digit divisor here.
195195
auto dividend = BigUIntView!uint.fromHexString("55a325ad18b2a77120d870d987d5237473790532acab45da44bc07c92c92babf");
196196
auto divisor = BigUIntView!uint.fromHexString("5");
197-
auto quotient = BigUIntView!uint.fromHexString("0000000000000000000000000000000000000000000000000000000000000000");
197+
auto quotient = BigUIntView!uint.fromHexString("1000000000000000000000000000000000000000000000000000000000000000");
198198
divMod(dividend, divisor, quotient);
199199
assert(dividend.normalized == BigUIntView!uint.fromHexString("3"));
200200
assert(quotient == BigUIntView!uint.fromHexString("1120a1229e8a217d0691b02b819107174a4b677088ef0df874259b283c1d588c"));
@@ -204,8 +204,8 @@ unittest
204204
{
205205
auto dividend = BigUIntView!uint.fromHexString("55a325ad18b2a77120d870d987d5237473790532acab45da44bc07c92c92babf0b5e2e2c7771cd472ae5d7acdb159a56fbf74f851a058ae341f69d1eb750d7e3");
206206
auto divisor = BigUIntView!uint.fromHexString("55e5669576d31726f4a9b58a90159de5923adc6c762ebd3c4ba518d495229072");
207-
auto quotient = BigUIntView!uint.fromHexString("00000000000000000000000000000000000000000000000000000000000000000");
208-
// auto remainder = BigUIntView!uint.fromHexString("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
207+
auto quotient = BigUIntView!uint.fromHexString("10000000000000000000000000000000000000000000000000000000000000000");
208+
// auto remainder = BigUIntView!uint.fromHexString("10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
209209

210210
divMod(dividend, divisor, quotient);
211211
assert(quotient.normalized == BigUIntView!uint.fromHexString("ff3a8aa4da35237811a0ffbf007fe938630dee8a810f2f82ae01f80c033291f6"));
@@ -216,8 +216,8 @@ unittest
216216
{
217217
auto dividend = BigUIntView!uint.fromHexString("800000000000000000000003");
218218
auto divisor = BigUIntView!uint.fromHexString("200000000000000000000001");
219-
auto quotient = BigUIntView!uint.fromHexString("0");
220-
// auto remainder = BigUIntView!uint.fromHexString("000000000000000000000000");
219+
auto quotient = BigUIntView!uint([0u]);
220+
// auto remainder = BigUIntView!uint.fromHexString("100000000000000000000000");
221221
divMod(dividend, divisor, quotient);
222222
assert(quotient == BigUIntView!uint.fromHexString("3"));
223223
assert(dividend == BigUIntView!uint.fromHexString("200000000000000000000000"));

source/mir/bignum/low_level_view.d

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,13 +220,15 @@ struct BigUIntView(W)
220220
/++
221221
+/
222222
BigUIntView topMostSignificantPart(size_t length)
223+
in (length <= coefficients.length)
223224
{
224225
return BigUIntView(coefficients[$ - length .. $]);
225226
}
226227

227228
/++
228229
+/
229230
BigUIntView topLeastSignificantPart(size_t length)
231+
in (length <= coefficients.length)
230232
{
231233
return BigUIntView(coefficients[0 .. length]);
232234
}
@@ -376,9 +378,13 @@ struct BigUIntView(W)
376378
current >>>= 4 * (W.sizeof * 2 - j % (W.sizeof * 2));
377379
work.coefficients[$ - 1] = current;
378380
}
381+
else
382+
{
383+
work.coefficients = work.coefficients[0 .. (j / (W.sizeof * 2) + (j % (W.sizeof * 2) != 0))];
384+
work = work.normalized;
385+
}
379386

380-
coefficients = coefficients[0 .. (j / (W.sizeof * 2) + (j % (W.sizeof * 2) != 0))];
381-
387+
this = work;
382388
return true;
383389
}
384390

@@ -475,9 +481,13 @@ struct BigUIntView(W)
475481
current >>>= (W.sizeof * 8 - j % (W.sizeof * 8));
476482
work.coefficients[$ - 1] = current;
477483
}
484+
else
485+
{
486+
work.coefficients = work.coefficients[0 .. (j / (W.sizeof * 8) + (j % (W.sizeof * 8) != 0))];
487+
work = work.normalized;
488+
}
478489

479-
coefficients = coefficients[0 .. (j / (W.sizeof * 8) + (j % (W.sizeof * 8) != 0))];
480-
490+
this = work;
481491
return true;
482492
}
483493

@@ -1007,8 +1017,9 @@ version(mir_bignum_test_llv)
10071017
@safe pure
10081018
unittest
10091019
{
1020+
import mir.test;
10101021
auto view = BigUIntView!size_t.fromHexString!(char, true)("abcd_efab_cdef");
1011-
assert(cast(ulong)view == 0xabcd_efab_cdef);
1022+
(cast(ulong)view).should == 0xabcd_efab_cdef;
10121023
}
10131024

10141025
///
@@ -1365,7 +1376,9 @@ struct BigIntView(W)
13651376
str = str[1 .. $];
13661377
}
13671378

1368-
return unsigned.fromHexStringImpl!(C, allowUnderscores)(str);
1379+
auto ret = unsigned.fromHexStringImpl!(C, allowUnderscores)(str);
1380+
sign = sign && unsigned.coefficients.length;
1381+
return ret;
13691382
}
13701383

13711384
/++
@@ -1412,7 +1425,9 @@ struct BigIntView(W)
14121425
str = str[1 .. $];
14131426
}
14141427

1415-
return unsigned.fromBinaryStringImpl!(C, allowUnderscores)(str);
1428+
auto ret = unsigned.fromBinaryStringImpl!(C, allowUnderscores)(str);
1429+
sign = sign && unsigned.coefficients.length;
1430+
return ret;
14161431
}
14171432

14181433
///

0 commit comments

Comments
 (0)