@@ -403,8 +403,7 @@ static void DivideAndConquer(ReadOnlySpan<uint> base1E9, int totalDigitCount, in
403
403
{
404
404
int valueDigits = ( base1E9 . Length - 1 ) * PowersOf1e9 . MaxPartialDigits + FormattingHelpers . CountDigits ( base1E9 [ ^ 1 ] ) ;
405
405
406
- int log2 = PowersOf1e9 . GetMaxIndex ( Math . Max ( valueDigits , trailingZeroCount + 1 ) ) ;
407
- int powersOf1e9BufferLength = PowersOf1e9 . GetBufferSize ( log2 ) ;
406
+ int powersOf1e9BufferLength = PowersOf1e9 . GetBufferSize ( Math . Max ( valueDigits , trailingZeroCount + 1 ) , out int maxIndex ) ;
408
407
uint [ ] ? powersOf1e9BufferFromPool = null ;
409
408
Span < uint > powersOf1e9Buffer = (
410
409
powersOf1e9BufferLength <= BigIntegerCalculator . StackAllocThreshold
@@ -424,7 +423,7 @@ static void DivideAndConquer(ReadOnlySpan<uint> base1E9, int totalDigitCount, in
424
423
: leadingFromPool = ArrayPool < uint > . Shared . Rent ( leadingLength ) ) . Slice ( 0 , leadingLength ) ;
425
424
leading . Clear ( ) ;
426
425
427
- Recursive ( powersOf1e9 , log2 , base1E9 , leading ) ;
426
+ Recursive ( powersOf1e9 , maxIndex , base1E9 , leading ) ;
428
427
leading = leading . Slice ( 0 , BigIntegerCalculator . ActualLength ( leading ) ) ;
429
428
430
429
powersOf1e9 . MultiplyPowerOfTen ( leading , trailingZeroCount , bits ) ;
@@ -434,7 +433,7 @@ static void DivideAndConquer(ReadOnlySpan<uint> base1E9, int totalDigitCount, in
434
433
}
435
434
else
436
435
{
437
- Recursive ( powersOf1e9 , log2 , base1E9 , bits ) ;
436
+ Recursive ( powersOf1e9 , maxIndex , base1E9 , bits ) ;
438
437
}
439
438
440
439
if ( powersOf1e9BufferFromPool != null )
@@ -461,12 +460,6 @@ static void Recursive(in PowersOf1e9 powersOf1e9, int powersOf1e9Index, ReadOnly
461
460
ReadOnlySpan < uint > multiplier = powersOf1e9 . GetSpan ( powersOf1e9Index ) ;
462
461
int multiplierTrailingZeroCount = PowersOf1e9 . OmittedLength ( powersOf1e9Index ) ;
463
462
464
- if ( multiplier1E9Length + multiplier1E9Length < base1E9 . Length )
465
- {
466
- RecursiveLarge ( powersOf1e9 , powersOf1e9Index , base1E9 , bits ) ;
467
- return ;
468
- }
469
-
470
463
Debug . Assert ( multiplier1E9Length < base1E9 . Length && base1E9 . Length <= multiplier1E9Length * 2 ) ;
471
464
472
465
int bufferLength = checked ( ( int ) ( digitRatio * PowersOf1e9 . MaxPartialDigits * multiplier1E9Length ) + 1 + 2 ) ;
@@ -496,67 +489,6 @@ static void Recursive(in PowersOf1e9 powersOf1e9, int powersOf1e9Index, ReadOnly
496
489
ArrayPool < uint > . Shared . Return ( bufferFromPool ) ;
497
490
}
498
491
499
- [ MethodImpl ( MethodImplOptions . NoInlining ) ]
500
- static void RecursiveLarge (
501
- in PowersOf1e9 powersOf1e9 , int powersOf1e9Index ,
502
- ReadOnlySpan < uint > base1E9 , scoped Span < uint > bits )
503
- {
504
- int multiplier1E9Length = 1 << powersOf1e9Index ;
505
- ReadOnlySpan < uint > multiplier = powersOf1e9 . GetSpan ( powersOf1e9Index ) ;
506
- int multiplierTrailingZeroCount = PowersOf1e9 . OmittedLength ( powersOf1e9Index ) ;
507
-
508
- Span < uint > bitsDst = bits ;
509
-
510
- uint [ ] ? bits2FromPool = null ;
511
- scoped Span < uint > bits2 = (
512
- bits . Length <= BigIntegerCalculator . StackAllocThreshold
513
- ? stackalloc uint [ BigIntegerCalculator . StackAllocThreshold ]
514
- : bits2FromPool = ArrayPool < uint > . Shared . Rent ( bits . Length ) ) . Slice ( 0 , bits . Length ) ;
515
- bits2 . Clear ( ) ;
516
-
517
- {
518
- int upperLength = base1E9 . Length & ( multiplier1E9Length - 1 ) ;
519
- if ( upperLength == 0 )
520
- upperLength = multiplier1E9Length ;
521
-
522
- Recursive ( powersOf1e9 , powersOf1e9Index - 1 , base1E9 [ ^ upperLength ..] , bits2 ) ;
523
-
524
- base1E9 = base1E9 [ ..^ upperLength ] ;
525
- }
526
-
527
- while ( base1E9 . Length > 0 )
528
- {
529
- ReadOnlySpan < uint > bitsPrev = bits2 . Slice ( 0 , BigIntegerCalculator . ActualLength ( bits2 ) ) ;
530
-
531
- Debug . Assert ( base1E9 . Length % multiplier1E9Length == 0 ) ;
532
- Span < uint > bitsUpper = bits . Slice ( multiplierTrailingZeroCount , bitsPrev . Length + multiplier . Length ) ;
533
- if ( multiplier . Length < bitsPrev . Length )
534
- BigIntegerCalculator . Multiply ( bitsPrev , multiplier , bitsUpper ) ;
535
- else
536
- BigIntegerCalculator . Multiply ( multiplier , bitsPrev , bitsUpper ) ;
537
-
538
- bits2 . Clear ( ) ;
539
- Recursive ( powersOf1e9 , powersOf1e9Index - 1 , base1E9 [ ^ multiplier1E9Length ..] , bits2 ) ;
540
-
541
- BigIntegerCalculator . AddSelf ( bits , bits2 ) ;
542
-
543
- base1E9 = base1E9 [ ..^ multiplier1E9Length ] ;
544
-
545
- Span < uint > bitsTmp = bits ;
546
- bits = bits2 ;
547
- bits2 = bitsTmp ;
548
- bits . Clear ( ) ;
549
- }
550
-
551
- if ( ! Unsafe . AreSame ( ref MemoryMarshal . GetReference ( bits2 ) , ref MemoryMarshal . GetReference ( bitsDst ) ) )
552
- {
553
- bits2 . CopyTo ( bitsDst ) ;
554
- }
555
-
556
- if ( bits2FromPool != null )
557
- ArrayPool < uint > . Shared . Return ( bits2FromPool ) ;
558
- }
559
-
560
492
static void Naive ( ReadOnlySpan < uint > base1E9 , int trailingZeroCount , scoped Span < uint > bits )
561
493
{
562
494
if ( base1E9 . Length == 0 )
@@ -1024,11 +956,6 @@ internal readonly ref struct PowersOf1e9
1024
956
// indexes[i+1] = indexes[i] + length;
1025
957
// }
1026
958
private static ReadOnlySpan < int > Indexes =>
1027
- #if DEBUG
1028
- IndexesArray ;
1029
-
1030
- public static int [ ] IndexesArray =
1031
- #endif
1032
959
[
1033
960
0 ,
1034
961
1 ,
@@ -1151,16 +1078,21 @@ public PowersOf1e9(Span<uint> pow1E9)
1151
1078
}
1152
1079
}
1153
1080
1154
- public static int GetMaxIndex ( int digits )
1081
+ public static int GetBufferSize ( int digits , out int maxIndex )
1155
1082
{
1156
1083
uint scale1E9 = ( uint ) ( digits - 1 ) / MaxPartialDigits ;
1157
- return BitOperations . Log2 ( scale1E9 ) ;
1158
- }
1084
+ maxIndex = BitOperations . Log2 ( scale1E9 ) ;
1085
+ int index = maxIndex + 1 ;
1086
+ int bufferSize ;
1087
+ if ( ( uint ) index < ( uint ) Indexes . Length )
1088
+ bufferSize = Indexes [ index ] ;
1089
+ else
1090
+ {
1091
+ maxIndex = Indexes . Length - 2 ;
1092
+ bufferSize = Indexes [ ^ 1 ] ;
1093
+ }
1159
1094
1160
- public static int GetBufferSize ( int index )
1161
- {
1162
- ++ index ;
1163
- return ( ( uint ) index < ( uint ) Indexes . Length ? Indexes [ index ] : Indexes [ ^ 1 ] ) + 1 ;
1095
+ return ++ bufferSize ;
1164
1096
}
1165
1097
1166
1098
public ReadOnlySpan < uint > GetSpan ( int index )
0 commit comments