@@ -320,6 +320,29 @@ private static ParsingStatus NumberToBigInteger(ref NumberBuffer number, out Big
320
320
return ParsingStatus . Failed ;
321
321
}
322
322
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
+
323
346
const double digitRatio = 0.10381025297 ; // log_{2^32}(10)
324
347
int resultLength = checked ( ( int ) ( number . Scale * digitRatio ) + 1 + 2 ) ;
325
348
uint [ ] ? resultBufferFromPool = null ;
@@ -329,12 +352,13 @@ private static ParsingStatus NumberToBigInteger(ref NumberBuffer number, out Big
329
352
: resultBufferFromPool = ArrayPool < uint > . Shared . Rent ( resultLength ) ) . Slice ( 0 , resultLength ) ;
330
353
resultBuffer . Clear ( ) ;
331
354
332
- if ( number . Scale <= BigIntegerParseNaiveThreshold
333
- ? ! Naive ( ref number , resultBuffer )
334
- : ! DivideAndConquer ( ref number , resultBuffer ) )
355
+ if ( number . Scale <= BigIntegerParseNaiveThreshold )
335
356
{
336
- result = default ;
337
- return ParsingStatus . Failed ;
357
+ Naive ( ref number , intDigits , resultBuffer ) ;
358
+ }
359
+ else
360
+ {
361
+ DivideAndConquer ( ref number , intDigits , resultBuffer ) ;
338
362
}
339
363
340
364
resultBuffer = resultBuffer . Slice ( 0 , BigIntegerCalculator . ActualLength ( resultBuffer ) ) ;
@@ -351,30 +375,8 @@ private static ParsingStatus NumberToBigInteger(ref NumberBuffer number, out Big
351
375
352
376
return ParsingStatus . OK ;
353
377
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 )
355
379
{
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
-
378
380
int totalDigitCount = Math . Min ( number . DigitsCount , number . Scale ) ;
379
381
int trailingZeroCount = number . Scale - totalDigitCount ;
380
382
@@ -415,8 +417,6 @@ static bool DivideAndConquer(ref NumberBuffer number, scoped Span<uint> bits)
415
417
416
418
if ( powersOf1e9BufferFromPool != null )
417
419
ArrayPool < uint > . Shared . Return ( powersOf1e9BufferFromPool ) ;
418
-
419
- return true ;
420
420
}
421
421
422
422
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)
514
514
return resultLength ;
515
515
}
516
516
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 )
518
518
{
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
-
542
519
int totalDigitCount = Math . Min ( number . DigitsCount , number . Scale ) ;
543
520
if ( totalDigitCount == 0 )
544
521
{
545
522
// number is 0.
546
- return true ;
523
+ return ;
547
524
}
548
525
int resultLength = NaiveDigits ( intDigits , bits ) ;
549
526
@@ -565,8 +542,6 @@ static bool Naive(ref NumberBuffer number, scoped Span<uint> bits)
565
542
if ( carry != 0 )
566
543
bits [ resultLength ++ ] = carry ;
567
544
}
568
-
569
- return true ;
570
545
}
571
546
572
547
static uint MultiplyAdd ( Span < uint > bits , uint multiplier , uint addValue )
0 commit comments