Skip to content

Commit 456bf8e

Browse files
committed
intDigits
1 parent 7568c5b commit 456bf8e

File tree

1 file changed

+32
-57
lines changed

1 file changed

+32
-57
lines changed

src/libraries/System.Runtime.Numerics/src/System/Number.BigInteger.cs

+32-57
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,29 @@ private static ParsingStatus NumberToBigInteger(ref NumberBuffer number, out Big
320320
return ParsingStatus.Failed;
321321
}
322322

323+
ReadOnlySpan<byte> intDigits = number.Digits.Slice(0, Math.Min(number.Scale, number.DigitsCount));
324+
int intDigitsEnd = intDigits.IndexOf<byte>(0);
325+
if (intDigitsEnd < 0)
326+
{
327+
// Check for nonzero digits after the decimal point.
328+
ReadOnlySpan<byte> fracDigitsSpan = number.Digits.Slice(intDigits.Length);
329+
for (int i = 0; i < fracDigitsSpan.Length; i++)
330+
{
331+
char digitChar = (char)fracDigitsSpan[i];
332+
if (digitChar == '\0')
333+
{
334+
break;
335+
}
336+
if (digitChar != '0')
337+
{
338+
result = default;
339+
return ParsingStatus.Failed;
340+
}
341+
}
342+
}
343+
else
344+
intDigits = intDigits.Slice(0, intDigitsEnd);
345+
323346
const double digitRatio = 0.10381025297; // log_{2^32}(10)
324347
int resultLength = checked((int)(number.Scale * digitRatio) + 1 + 2);
325348
uint[]? resultBufferFromPool = null;
@@ -329,12 +352,13 @@ private static ParsingStatus NumberToBigInteger(ref NumberBuffer number, out Big
329352
: resultBufferFromPool = ArrayPool<uint>.Shared.Rent(resultLength)).Slice(0, resultLength);
330353
resultBuffer.Clear();
331354

332-
if (number.Scale <= BigIntegerParseNaiveThreshold
333-
? !Naive(ref number, resultBuffer)
334-
: !DivideAndConquer(ref number, resultBuffer))
355+
if (number.Scale <= BigIntegerParseNaiveThreshold)
335356
{
336-
result = default;
337-
return ParsingStatus.Failed;
357+
Naive(ref number, intDigits, resultBuffer);
358+
}
359+
else
360+
{
361+
DivideAndConquer(ref number, intDigits, resultBuffer);
338362
}
339363

340364
resultBuffer = resultBuffer.Slice(0, BigIntegerCalculator.ActualLength(resultBuffer));
@@ -351,30 +375,8 @@ private static ParsingStatus NumberToBigInteger(ref NumberBuffer number, out Big
351375

352376
return ParsingStatus.OK;
353377

354-
static bool DivideAndConquer(ref NumberBuffer number, scoped Span<uint> bits)
378+
static void DivideAndConquer(ref NumberBuffer number, ReadOnlySpan<byte> intDigits, scoped Span<uint> bits)
355379
{
356-
ReadOnlySpan<byte> intDigits = number.Digits.Slice(0, Math.Min(number.Scale, number.DigitsCount));
357-
int intDigitsEnd = intDigits.IndexOf<byte>(0);
358-
if (intDigitsEnd < 0)
359-
{
360-
// Check for nonzero digits after the decimal point.
361-
ReadOnlySpan<byte> fracDigitsSpan = number.Digits.Slice(intDigits.Length);
362-
for (int i = 0; i < fracDigitsSpan.Length; i++)
363-
{
364-
char digitChar = (char)fracDigitsSpan[i];
365-
if (digitChar == '\0')
366-
{
367-
break;
368-
}
369-
if (digitChar != '0')
370-
{
371-
return false;
372-
}
373-
}
374-
}
375-
else
376-
intDigits = intDigits.Slice(0, intDigitsEnd);
377-
378380
int totalDigitCount = Math.Min(number.DigitsCount, number.Scale);
379381
int trailingZeroCount = number.Scale - totalDigitCount;
380382

@@ -415,8 +417,6 @@ static bool DivideAndConquer(ref NumberBuffer number, scoped Span<uint> bits)
415417

416418
if (powersOf1e9BufferFromPool != null)
417419
ArrayPool<uint>.Shared.Return(powersOf1e9BufferFromPool);
418-
419-
return true;
420420
}
421421

422422
static void Recursive(in PowersOf1e9 powersOf1e9, ReadOnlySpan<byte> digits, Span<uint> bits)
@@ -514,36 +514,13 @@ static int NaiveDigits(ReadOnlySpan<byte> intDigits, Span<uint> bits)
514514
return resultLength;
515515
}
516516

517-
static bool Naive(ref NumberBuffer number, scoped Span<uint> bits)
517+
static void Naive(ref NumberBuffer number, ReadOnlySpan<byte> intDigits, scoped Span<uint> bits)
518518
{
519-
ReadOnlySpan<byte> intDigits = number.Digits.Slice(0, Math.Min(number.Scale, number.DigitsCount));
520-
int intDigitsEnd = intDigits.IndexOf<byte>(0);
521-
if (intDigitsEnd < 0)
522-
{
523-
// Check for nonzero digits after the decimal point.
524-
ReadOnlySpan<byte> fracDigitsSpan = number.Digits.Slice(intDigits.Length);
525-
for (int i = 0; i < fracDigitsSpan.Length; i++)
526-
{
527-
char digitChar = (char)fracDigitsSpan[i];
528-
if (digitChar == '\0')
529-
{
530-
break;
531-
}
532-
if (digitChar != '0')
533-
{
534-
return false;
535-
}
536-
}
537-
}
538-
else
539-
intDigits = intDigits.Slice(0, intDigitsEnd);
540-
541-
542519
int totalDigitCount = Math.Min(number.DigitsCount, number.Scale);
543520
if (totalDigitCount == 0)
544521
{
545522
// number is 0.
546-
return true;
523+
return;
547524
}
548525
int resultLength = NaiveDigits(intDigits, bits);
549526

@@ -565,8 +542,6 @@ static bool Naive(ref NumberBuffer number, scoped Span<uint> bits)
565542
if (carry != 0)
566543
bits[resultLength++] = carry;
567544
}
568-
569-
return true;
570545
}
571546

572547
static uint MultiplyAdd(Span<uint> bits, uint multiplier, uint addValue)

0 commit comments

Comments
 (0)