Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
BigInteger.cs
Go to the documentation of this file.
4
5namespace System.Numerics;
6
8[TypeForwardedFrom("System.Numerics, Version=4.0.0.0, PublicKeyToken=b77a5c561934e089")]
9public readonly struct BigInteger : ISpanFormattable, IFormattable, IComparable, IComparable<BigInteger>, IEquatable<BigInteger>
10{
11 private enum GetBytesMode
12 {
14 Count,
15 Span
16 }
17
18 internal readonly int _sign;
19
20 internal readonly uint[] _bits;
21
22 private static readonly BigInteger s_bnMinInt = new BigInteger(-1, new uint[1] { 2147483648u });
23
24 private static readonly BigInteger s_bnOneInt = new BigInteger(1);
25
26 private static readonly BigInteger s_bnZeroInt = new BigInteger(0);
27
28 private static readonly BigInteger s_bnMinusOneInt = new BigInteger(-1);
29
30 private static readonly byte[] s_success = Array.Empty<byte>();
31
32 public static BigInteger Zero => s_bnZeroInt;
33
34 public static BigInteger One => s_bnOneInt;
35
37
38 public bool IsPowerOfTwo
39 {
40 get
41 {
42 if (_bits == null)
43 {
44 if ((_sign & (_sign - 1)) == 0)
45 {
46 return _sign != 0;
47 }
48 return false;
49 }
50 if (_sign != 1)
51 {
52 return false;
53 }
54 int num = _bits.Length - 1;
55 if ((_bits[num] & (_bits[num] - 1)) != 0)
56 {
57 return false;
58 }
59 while (--num >= 0)
60 {
61 if (_bits[num] != 0)
62 {
63 return false;
64 }
65 }
66 return true;
67 }
68 }
69
70 public bool IsZero => _sign == 0;
71
72 public bool IsOne
73 {
74 get
75 {
76 if (_sign == 1)
77 {
78 return _bits == null;
79 }
80 return false;
81 }
82 }
83
84 public bool IsEven
85 {
86 get
87 {
88 if (_bits != null)
89 {
90 return (_bits[0] & 1) == 0;
91 }
92 return (_sign & 1) == 0;
93 }
94 }
95
96 public int Sign => (_sign >> 31) - (-_sign >> 31);
97
98 public BigInteger(int value)
99 {
100 if (value == int.MinValue)
101 {
102 this = s_bnMinInt;
103 return;
104 }
105 _sign = value;
106 _bits = null;
107 }
108
109 [CLSCompliant(false)]
110 public BigInteger(uint value)
111 {
112 if (value <= int.MaxValue)
113 {
114 _sign = (int)value;
115 _bits = null;
116 }
117 else
118 {
119 _sign = 1;
120 _bits = new uint[1];
121 _bits[0] = value;
122 }
123 }
124
125 public BigInteger(long value)
126 {
127 if (int.MinValue < value && value <= int.MaxValue)
128 {
129 _sign = (int)value;
130 _bits = null;
131 return;
132 }
133 if (value == int.MinValue)
134 {
135 this = s_bnMinInt;
136 return;
137 }
138 ulong num = 0uL;
139 if (value < 0)
140 {
141 num = (ulong)(-value);
142 _sign = -1;
143 }
144 else
145 {
146 num = (ulong)value;
147 _sign = 1;
148 }
149 if (num <= uint.MaxValue)
150 {
151 _bits = new uint[1];
152 _bits[0] = (uint)num;
153 }
154 else
155 {
156 _bits = new uint[2];
157 _bits[0] = (uint)num;
158 _bits[1] = (uint)(num >> 32);
159 }
160 }
161
162 [CLSCompliant(false)]
163 public BigInteger(ulong value)
164 {
165 if (value <= int.MaxValue)
166 {
167 _sign = (int)value;
168 _bits = null;
169 }
170 else if (value <= uint.MaxValue)
171 {
172 _sign = 1;
173 _bits = new uint[1];
174 _bits[0] = (uint)value;
175 }
176 else
177 {
178 _sign = 1;
179 _bits = new uint[2];
180 _bits[0] = (uint)value;
181 _bits[1] = (uint)(value >> 32);
182 }
183 }
184
185 public BigInteger(float value)
186 : this((double)value)
187 {
188 }
189
190 public BigInteger(double value)
191 {
192 if (!double.IsFinite(value))
193 {
194 if (double.IsInfinity(value))
195 {
197 }
199 }
200 _sign = 0;
201 _bits = null;
202 NumericsHelpers.GetDoubleParts(value, out var sign, out var exp, out var man, out var _);
203 if (man == 0L)
204 {
205 this = Zero;
206 return;
207 }
208 if (exp <= 0)
209 {
210 if (exp <= -64)
211 {
212 this = Zero;
213 return;
214 }
215 this = man >> -exp;
216 if (sign < 0)
217 {
218 _sign = -_sign;
219 }
220 return;
221 }
222 if (exp <= 11)
223 {
224 this = man << exp;
225 if (sign < 0)
226 {
227 _sign = -_sign;
228 }
229 return;
230 }
231 man <<= 11;
232 exp -= 11;
233 int num = (exp - 1) / 32 + 1;
234 int num2 = num * 32 - exp;
235 _bits = new uint[num + 2];
236 _bits[num + 1] = (uint)(man >> num2 + 32);
237 _bits[num] = (uint)(man >> num2);
238 if (num2 > 0)
239 {
240 _bits[num - 1] = (uint)((int)man << 32 - num2);
241 }
242 _sign = sign;
243 }
244
245 public BigInteger(decimal value)
246 {
247 Span<int> destination = stackalloc int[4];
248 decimal.GetBits(decimal.Truncate(value), destination);
249 int num = 3;
250 while (num > 0 && destination[num - 1] == 0)
251 {
252 num--;
253 }
254 switch (num)
255 {
256 case 0:
257 this = s_bnZeroInt;
258 return;
259 case 1:
260 if (destination[0] > 0)
261 {
262 _sign = destination[0];
263 _sign *= (((destination[3] & int.MinValue) == 0) ? 1 : (-1));
264 _bits = null;
265 return;
266 }
267 break;
268 }
269 _bits = new uint[num];
270 _bits[0] = (uint)destination[0];
271 if (num > 1)
272 {
273 _bits[1] = (uint)destination[1];
274 }
275 if (num > 2)
276 {
277 _bits[2] = (uint)destination[2];
278 }
279 _sign = (((destination[3] & int.MinValue) == 0) ? 1 : (-1));
280 }
281
282 [CLSCompliant(false)]
283 public BigInteger(byte[] value)
284 : this(new ReadOnlySpan<byte>(value ?? throw new ArgumentNullException("value")))
285 {
286 }
287
288 public BigInteger(ReadOnlySpan<byte> value, bool isUnsigned = false, bool isBigEndian = false)
289 {
290 int num = value.Length;
291 bool flag;
292 if (num > 0)
293 {
294 byte b = (isBigEndian ? value[0] : value[num - 1]);
295 flag = (b & 0x80u) != 0 && !isUnsigned;
296 if (b == 0)
297 {
298 if (isBigEndian)
299 {
300 int i;
301 for (i = 1; i < num && value[i] == 0; i++)
302 {
303 }
304 value = value.Slice(i);
305 num = value.Length;
306 }
307 else
308 {
309 num -= 2;
310 while (num >= 0 && value[num] == 0)
311 {
312 num--;
313 }
314 num++;
315 }
316 }
317 }
318 else
319 {
320 flag = false;
321 }
322 if (num == 0)
323 {
324 _sign = 0;
325 _bits = null;
326 return;
327 }
328 if (num <= 4)
329 {
330 _sign = (flag ? (-1) : 0);
331 if (isBigEndian)
332 {
333 for (int j = 0; j < num; j++)
334 {
335 _sign = (_sign << 8) | value[j];
336 }
337 }
338 else
339 {
340 for (int num2 = num - 1; num2 >= 0; num2--)
341 {
342 _sign = (_sign << 8) | value[num2];
343 }
344 }
345 _bits = null;
346 if (_sign < 0 && !flag)
347 {
348 _bits = new uint[1] { (uint)_sign };
349 _sign = 1;
350 }
351 if (_sign == int.MinValue)
352 {
353 this = s_bnMinInt;
354 }
355 return;
356 }
357 int num3 = num % 4;
358 int num4 = num / 4 + ((num3 != 0) ? 1 : 0);
359 uint[] array = new uint[num4];
360 int num5 = num - 1;
361 int k;
362 if (isBigEndian)
363 {
364 int num6 = num - 4;
365 for (k = 0; k < num4 - ((num3 != 0) ? 1 : 0); k++)
366 {
367 for (int l = 0; l < 4; l++)
368 {
369 byte b2 = value[num6];
370 array[k] = (array[k] << 8) | b2;
371 num6++;
372 }
373 num6 -= 8;
374 }
375 }
376 else
377 {
378 int num6 = 3;
379 for (k = 0; k < num4 - ((num3 != 0) ? 1 : 0); k++)
380 {
381 for (int m = 0; m < 4; m++)
382 {
383 byte b3 = value[num6];
384 array[k] = (array[k] << 8) | b3;
385 num6--;
386 }
387 num6 += 8;
388 }
389 }
390 if (num3 != 0)
391 {
392 if (flag)
393 {
394 array[num4 - 1] = uint.MaxValue;
395 }
396 if (isBigEndian)
397 {
398 for (int num6 = 0; num6 < num3; num6++)
399 {
400 byte b4 = value[num6];
401 array[k] = (array[k] << 8) | b4;
402 }
403 }
404 else
405 {
406 for (int num6 = num5; num6 >= num - num3; num6--)
407 {
408 byte b5 = value[num6];
409 array[k] = (array[k] << 8) | b5;
410 }
411 }
412 }
413 if (flag)
414 {
416 int num7 = array.Length - 1;
417 while (num7 >= 0 && array[num7] == 0)
418 {
419 num7--;
420 }
421 num7++;
422 if (num7 == 1)
423 {
424 switch (array[0])
425 {
426 case 1u:
427 this = s_bnMinusOneInt;
428 return;
429 case 2147483648u:
430 this = s_bnMinInt;
431 return;
432 }
433 if ((int)array[0] > 0)
434 {
435 _sign = -1 * (int)array[0];
436 _bits = null;
437 return;
438 }
439 }
440 if (num7 != array.Length)
441 {
442 _sign = -1;
443 _bits = new uint[num7];
444 Array.Copy(array, _bits, num7);
445 }
446 else
447 {
448 _sign = -1;
449 _bits = array;
450 }
451 }
452 else
453 {
454 _sign = 1;
455 _bits = array;
456 }
457 }
458
459 internal BigInteger(int n, uint[] rgu)
460 {
461 _sign = n;
462 _bits = rgu;
463 }
464
465 private BigInteger(ReadOnlySpan<uint> value, uint[] valueArray, bool negative)
466 {
467 if (!value.IsEmpty && value[^1] == 0)
468 {
469 int num = value.Length - 1;
470 while (num > 0 && value[num - 1] == 0)
471 {
472 num--;
473 }
474 value = value.Slice(0, num);
475 valueArray = null;
476 }
477 if (value.IsEmpty)
478 {
479 this = s_bnZeroInt;
480 }
481 else if (value.Length == 1 && value[0] < 2147483648u)
482 {
483 _sign = (int)(negative ? (0 - value[0]) : value[0]);
484 _bits = null;
485 if (_sign == int.MinValue)
486 {
487 this = s_bnMinInt;
488 }
489 }
490 else
491 {
492 _sign = ((!negative) ? 1 : (-1));
493 _bits = valueArray ?? value.ToArray();
494 }
495 }
496
497 private BigInteger(uint[] value)
498 {
499 if (value == null)
500 {
501 throw new ArgumentNullException("value");
502 }
503 int num = value.Length;
504 bool flag = num > 0 && (value[num - 1] & 0x80000000u) == 2147483648u;
505 while (num > 0 && value[num - 1] == 0)
506 {
507 num--;
508 }
509 switch (num)
510 {
511 case 0:
512 this = s_bnZeroInt;
513 return;
514 case 1:
515 if ((int)value[0] < 0 && !flag)
516 {
517 _bits = new uint[1];
518 _bits[0] = value[0];
519 _sign = 1;
520 }
521 else if (int.MinValue == (int)value[0])
522 {
523 this = s_bnMinInt;
524 }
525 else
526 {
527 _sign = (int)value[0];
528 _bits = null;
529 }
530 return;
531 }
532 if (!flag)
533 {
534 if (num != value.Length)
535 {
536 _sign = 1;
537 _bits = new uint[num];
538 Array.Copy(value, _bits, num);
539 }
540 else
541 {
542 _sign = 1;
543 _bits = value;
544 }
545 return;
546 }
548 int num2 = value.Length;
549 while (num2 > 0 && value[num2 - 1] == 0)
550 {
551 num2--;
552 }
553 if (num2 == 1 && (int)value[0] > 0)
554 {
555 if (value[0] == 1)
556 {
557 this = s_bnMinusOneInt;
558 return;
559 }
560 if (value[0] == 2147483648u)
561 {
562 this = s_bnMinInt;
563 return;
564 }
565 _sign = -1 * (int)value[0];
566 _bits = null;
567 }
568 else if (num2 != value.Length)
569 {
570 _sign = -1;
571 _bits = new uint[num2];
572 Array.Copy(value, _bits, num2);
573 }
574 else
575 {
576 _sign = -1;
577 _bits = value;
578 }
579 }
580
581 public static BigInteger Parse(string value)
582 {
583 return Parse(value, NumberStyles.Integer);
584 }
585
586 public static BigInteger Parse(string value, NumberStyles style)
587 {
588 return Parse(value, style, NumberFormatInfo.CurrentInfo);
589 }
590
591 public static BigInteger Parse(string value, IFormatProvider? provider)
592 {
593 return Parse(value, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider));
594 }
595
596 public static BigInteger Parse(string value, NumberStyles style, IFormatProvider? provider)
597 {
599 }
600
601 public static bool TryParse([NotNullWhen(true)] string? value, out BigInteger result)
602 {
603 return TryParse(value, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
604 }
605
606 public static bool TryParse([NotNullWhen(true)] string? value, NumberStyles style, IFormatProvider? provider, out BigInteger result)
607 {
608 return BigNumber.TryParseBigInteger(value, style, NumberFormatInfo.GetInstance(provider), out result);
609 }
610
611 public static BigInteger Parse(ReadOnlySpan<char> value, NumberStyles style = NumberStyles.Integer, IFormatProvider? provider = null)
612 {
614 }
615
616 public static bool TryParse(ReadOnlySpan<char> value, out BigInteger result)
617 {
618 return TryParse(value, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
619 }
620
621 public static bool TryParse(ReadOnlySpan<char> value, NumberStyles style, IFormatProvider? provider, out BigInteger result)
622 {
623 return BigNumber.TryParseBigInteger(value, style, NumberFormatInfo.GetInstance(provider), out result);
624 }
625
626 public static int Compare(BigInteger left, BigInteger right)
627 {
628 return left.CompareTo(right);
629 }
630
632 {
633 if (!(value >= Zero))
634 {
635 return -value;
636 }
637 return value;
638 }
639
640 public static BigInteger Add(BigInteger left, BigInteger right)
641 {
642 return left + right;
643 }
644
645 public static BigInteger Subtract(BigInteger left, BigInteger right)
646 {
647 return left - right;
648 }
649
650 public static BigInteger Multiply(BigInteger left, BigInteger right)
651 {
652 return left * right;
653 }
654
655 public static BigInteger Divide(BigInteger dividend, BigInteger divisor)
656 {
657 return dividend / divisor;
658 }
659
660 public static BigInteger Remainder(BigInteger dividend, BigInteger divisor)
661 {
662 return dividend % divisor;
663 }
664
665 public static BigInteger DivRem(BigInteger dividend, BigInteger divisor, out BigInteger remainder)
666 {
667 bool flag = dividend._bits == null;
668 bool flag2 = divisor._bits == null;
669 if (flag && flag2)
670 {
671 (int Quotient, int Remainder) tuple = Math.DivRem(dividend._sign, divisor._sign);
672 BigInteger bigInteger = tuple.Quotient;
673 BigInteger bigInteger2 = tuple.Remainder;
674 BigInteger result = bigInteger;
675 remainder = bigInteger2;
676 return result;
677 }
678 if (flag)
679 {
680 remainder = dividend;
681 return s_bnZeroInt;
682 }
683 if (flag2)
684 {
685 uint remainder2;
686 uint[] array = BigIntegerCalculator.Divide(dividend._bits, NumericsHelpers.Abs(divisor._sign), out remainder2);
687 remainder = ((dividend._sign < 0) ? (-1 * remainder2) : remainder2);
688 return new BigInteger(array, array, (dividend._sign < 0) ^ (divisor._sign < 0));
689 }
690 if (dividend._bits.Length < divisor._bits.Length)
691 {
692 remainder = dividend;
693 return s_bnZeroInt;
694 }
695 uint[] remainder3;
696 uint[] array2 = BigIntegerCalculator.Divide(dividend._bits, divisor._bits, out remainder3);
697 remainder = new BigInteger(remainder3, remainder3, dividend._sign < 0);
698 return new BigInteger(array2, array2, (dividend._sign < 0) ^ (divisor._sign < 0));
699 }
700
702 {
703 return -value;
704 }
705
706 public static double Log(BigInteger value)
707 {
708 return Log(value, Math.E);
709 }
710
711 public static double Log(BigInteger value, double baseValue)
712 {
713 if (value._sign < 0 || baseValue == 1.0)
714 {
715 return double.NaN;
716 }
717 if (baseValue == double.PositiveInfinity)
718 {
719 if (!value.IsOne)
720 {
721 return double.NaN;
722 }
723 return 0.0;
724 }
725 if (baseValue == 0.0 && !value.IsOne)
726 {
727 return double.NaN;
728 }
729 if (value._bits == null)
730 {
731 return Math.Log(value._sign, baseValue);
732 }
733 ulong num = value._bits[value._bits.Length - 1];
734 ulong num2 = ((value._bits.Length > 1) ? value._bits[value._bits.Length - 2] : 0u);
735 ulong num3 = ((value._bits.Length > 2) ? value._bits[value._bits.Length - 3] : 0u);
736 int num4 = NumericsHelpers.CbitHighZero((uint)num);
737 long num5 = (long)value._bits.Length * 32L - num4;
738 ulong num6 = (num << 32 + num4) | (num2 << num4) | (num3 >> 32 - num4);
739 return Math.Log(num6, baseValue) + (double)(num5 - 64) / Math.Log(baseValue, 2.0);
740 }
741
742 public static double Log10(BigInteger value)
743 {
744 return Log(value, 10.0);
745 }
746
748 {
749 bool flag = left._bits == null;
750 bool flag2 = right._bits == null;
751 if (flag && flag2)
752 {
754 }
755 if (flag)
756 {
757 if (left._sign == 0)
758 {
759 return new BigInteger(right._bits, null, negative: false);
760 }
762 }
763 if (flag2)
764 {
765 if (right._sign == 0)
766 {
767 return new BigInteger(left._bits, null, negative: false);
768 }
770 }
771 if (BigIntegerCalculator.Compare(left._bits, right._bits) < 0)
772 {
773 return GreatestCommonDivisor(right._bits, left._bits);
774 }
775 return GreatestCommonDivisor(left._bits, right._bits);
776 }
777
778 private static BigInteger GreatestCommonDivisor(uint[] leftBits, uint[] rightBits)
779 {
780 if (rightBits.Length == 1)
781 {
782 uint right = BigIntegerCalculator.Remainder(leftBits, rightBits[0]);
783 return BigIntegerCalculator.Gcd(rightBits[0], right);
784 }
785 if (rightBits.Length == 2)
786 {
787 uint[] array = BigIntegerCalculator.Remainder(leftBits, rightBits);
788 ulong left = ((ulong)rightBits[1] << 32) | rightBits[0];
789 ulong right2 = ((ulong)array[1] << 32) | array[0];
790 return BigIntegerCalculator.Gcd(left, right2);
791 }
792 uint[] array2 = BigIntegerCalculator.Gcd(leftBits, rightBits);
793 return new BigInteger(array2, array2, negative: false);
794 }
795
796 public static BigInteger Max(BigInteger left, BigInteger right)
797 {
798 if (left.CompareTo(right) < 0)
799 {
800 return right;
801 }
802 return left;
803 }
804
805 public static BigInteger Min(BigInteger left, BigInteger right)
806 {
807 if (left.CompareTo(right) <= 0)
808 {
809 return left;
810 }
811 return right;
812 }
813
814 public static BigInteger ModPow(BigInteger value, BigInteger exponent, BigInteger modulus)
815 {
816 if (exponent.Sign < 0)
817 {
819 }
820 bool flag = value._bits == null;
821 bool flag2 = exponent._bits == null;
822 if (modulus._bits == null)
823 {
824 uint num = ((flag && flag2) ? BigIntegerCalculator.Pow(NumericsHelpers.Abs(value._sign), NumericsHelpers.Abs(exponent._sign), NumericsHelpers.Abs(modulus._sign)) : (flag ? BigIntegerCalculator.Pow(NumericsHelpers.Abs(value._sign), exponent._bits, NumericsHelpers.Abs(modulus._sign)) : (flag2 ? BigIntegerCalculator.Pow(value._bits, NumericsHelpers.Abs(exponent._sign), NumericsHelpers.Abs(modulus._sign)) : BigIntegerCalculator.Pow(value._bits, exponent._bits, NumericsHelpers.Abs(modulus._sign)))));
825 return (value._sign < 0 && !exponent.IsEven) ? (-1 * num) : num;
826 }
827 uint[] array = ((flag && flag2) ? BigIntegerCalculator.Pow(NumericsHelpers.Abs(value._sign), NumericsHelpers.Abs(exponent._sign), modulus._bits) : (flag ? BigIntegerCalculator.Pow(NumericsHelpers.Abs(value._sign), exponent._bits, modulus._bits) : (flag2 ? BigIntegerCalculator.Pow(value._bits, NumericsHelpers.Abs(exponent._sign), modulus._bits) : BigIntegerCalculator.Pow(value._bits, exponent._bits, modulus._bits))));
828 return new BigInteger(array, array, value._sign < 0 && !exponent.IsEven);
829 }
830
831 public static BigInteger Pow(BigInteger value, int exponent)
832 {
833 if (exponent < 0)
834 {
836 }
837 switch (exponent)
838 {
839 case 0:
840 return s_bnOneInt;
841 case 1:
842 return value;
843 default:
844 {
845 bool flag = value._bits == null;
846 if (flag)
847 {
848 if (value._sign == 1)
849 {
850 return value;
851 }
852 if (value._sign == -1)
853 {
854 if ((exponent & 1) == 0)
855 {
856 return s_bnOneInt;
857 }
858 return value;
859 }
860 if (value._sign == 0)
861 {
862 return value;
863 }
864 }
866 return new BigInteger(array, array, value._sign < 0 && (exponent & 1) != 0);
867 }
868 }
869 }
870
871 public override int GetHashCode()
872 {
873 if (_bits == null)
874 {
875 return _sign;
876 }
877 int num = _sign;
878 int num2 = _bits.Length;
879 while (--num2 >= 0)
880 {
881 num = NumericsHelpers.CombineHash(num, (int)_bits[num2]);
882 }
883 return num;
884 }
885
886 public override bool Equals([NotNullWhen(true)] object? obj)
887 {
888 if (!(obj is BigInteger))
889 {
890 return false;
891 }
892 return Equals((BigInteger)obj);
893 }
894
895 public bool Equals(long other)
896 {
897 if (_bits == null)
898 {
899 return _sign == other;
900 }
901 int num;
902 if ((_sign ^ other) < 0 || (num = _bits.Length) > 2)
903 {
904 return false;
905 }
906 ulong num2 = (ulong)((other < 0) ? (-other) : other);
907 if (num == 1)
908 {
909 return _bits[0] == num2;
910 }
911 return NumericsHelpers.MakeUlong(_bits[1], _bits[0]) == num2;
912 }
913
914 [CLSCompliant(false)]
915 public bool Equals(ulong other)
916 {
917 if (_sign < 0)
918 {
919 return false;
920 }
921 if (_bits == null)
922 {
923 return (ulong)_sign == other;
924 }
925 int num = _bits.Length;
926 if (num > 2)
927 {
928 return false;
929 }
930 if (num == 1)
931 {
932 return _bits[0] == other;
933 }
934 return NumericsHelpers.MakeUlong(_bits[1], _bits[0]) == other;
935 }
936
938 {
939 if (_sign != other._sign)
940 {
941 return false;
942 }
943 if (_bits == other._bits)
944 {
945 return true;
946 }
947 if (_bits == null || other._bits == null)
948 {
949 return false;
950 }
951 int num = _bits.Length;
952 if (num != other._bits.Length)
953 {
954 return false;
955 }
956 int diffLength = GetDiffLength(_bits, other._bits, num);
957 return diffLength == 0;
958 }
959
960 public int CompareTo(long other)
961 {
962 if (_bits == null)
963 {
964 return ((long)_sign).CompareTo(other);
965 }
966 int num;
967 if ((_sign ^ other) < 0 || (num = _bits.Length) > 2)
968 {
969 return _sign;
970 }
971 ulong value = (ulong)((other < 0) ? (-other) : other);
972 ulong num2 = ((num == 2) ? NumericsHelpers.MakeUlong(_bits[1], _bits[0]) : _bits[0]);
973 return _sign * num2.CompareTo(value);
974 }
975
976 [CLSCompliant(false)]
977 public int CompareTo(ulong other)
978 {
979 if (_sign < 0)
980 {
981 return -1;
982 }
983 if (_bits == null)
984 {
985 return ((ulong)_sign).CompareTo(other);
986 }
987 int num = _bits.Length;
988 if (num > 2)
989 {
990 return 1;
991 }
992 return ((num == 2) ? NumericsHelpers.MakeUlong(_bits[1], _bits[0]) : _bits[0]).CompareTo(other);
993 }
994
996 {
997 if ((_sign ^ other._sign) < 0)
998 {
999 if (_sign >= 0)
1000 {
1001 return 1;
1002 }
1003 return -1;
1004 }
1005 if (_bits == null)
1006 {
1007 if (other._bits == null)
1008 {
1009 if (_sign >= other._sign)
1010 {
1011 if (_sign <= other._sign)
1012 {
1013 return 0;
1014 }
1015 return 1;
1016 }
1017 return -1;
1018 }
1019 return -other._sign;
1020 }
1021 int num;
1022 int num2;
1023 if (other._bits == null || (num = _bits.Length) > (num2 = other._bits.Length))
1024 {
1025 return _sign;
1026 }
1027 if (num < num2)
1028 {
1029 return -_sign;
1030 }
1031 int diffLength = GetDiffLength(_bits, other._bits, num);
1032 if (diffLength == 0)
1033 {
1034 return 0;
1035 }
1036 if (_bits[diffLength - 1] >= other._bits[diffLength - 1])
1037 {
1038 return _sign;
1039 }
1040 return -_sign;
1041 }
1042
1043 public int CompareTo(object? obj)
1044 {
1045 if (obj == null)
1046 {
1047 return 1;
1048 }
1049 if (!(obj is BigInteger))
1050 {
1052 }
1053 return CompareTo((BigInteger)obj);
1054 }
1055
1056 public byte[] ToByteArray()
1057 {
1058 return ToByteArray(isUnsigned: false, isBigEndian: false);
1059 }
1060
1061 public byte[] ToByteArray(bool isUnsigned = false, bool isBigEndian = false)
1062 {
1063 int bytesWritten = 0;
1064 return TryGetBytes(GetBytesMode.AllocateArray, default(Span<byte>), isUnsigned, isBigEndian, ref bytesWritten);
1065 }
1066
1067 public bool TryWriteBytes(Span<byte> destination, out int bytesWritten, bool isUnsigned = false, bool isBigEndian = false)
1068 {
1069 bytesWritten = 0;
1070 if (TryGetBytes(GetBytesMode.Span, destination, isUnsigned, isBigEndian, ref bytesWritten) == null)
1071 {
1072 bytesWritten = 0;
1073 return false;
1074 }
1075 return true;
1076 }
1077
1078 internal bool TryWriteOrCountBytes(Span<byte> destination, out int bytesWritten, bool isUnsigned = false, bool isBigEndian = false)
1079 {
1080 bytesWritten = 0;
1081 return TryGetBytes(GetBytesMode.Span, destination, isUnsigned, isBigEndian, ref bytesWritten) != null;
1082 }
1083
1084 public int GetByteCount(bool isUnsigned = false)
1085 {
1086 int bytesWritten = 0;
1087 TryGetBytes(GetBytesMode.Count, default(Span<byte>), isUnsigned, isBigEndian: false, ref bytesWritten);
1088 return bytesWritten;
1089 }
1090
1091 private byte[] TryGetBytes(GetBytesMode mode, Span<byte> destination, bool isUnsigned, bool isBigEndian, ref int bytesWritten)
1092 {
1093 int sign = _sign;
1094 if (sign == 0)
1095 {
1096 switch (mode)
1097 {
1098 case GetBytesMode.AllocateArray:
1099 return new byte[1];
1100 case GetBytesMode.Count:
1101 bytesWritten = 1;
1102 return null;
1103 default:
1104 bytesWritten = 1;
1105 if (destination.Length != 0)
1106 {
1107 destination[0] = 0;
1108 return s_success;
1109 }
1110 return null;
1111 }
1112 }
1113 if (isUnsigned && sign < 0)
1114 {
1116 }
1117 int i = 0;
1118 uint[] bits = _bits;
1119 byte b;
1120 uint num;
1121 if (bits == null)
1122 {
1123 b = (byte)((sign < 0) ? 255u : 0u);
1124 num = (uint)sign;
1125 }
1126 else if (sign == -1)
1127 {
1128 b = byte.MaxValue;
1129 for (; bits[i] == 0; i++)
1130 {
1131 }
1132 num = ~bits[^1];
1133 if (bits.Length - 1 == i)
1134 {
1135 num++;
1136 }
1137 }
1138 else
1139 {
1140 b = 0;
1141 num = bits[^1];
1142 }
1143 byte b2;
1144 int num2;
1145 if ((b2 = (byte)(num >> 24)) != b)
1146 {
1147 num2 = 3;
1148 }
1149 else if ((b2 = (byte)(num >> 16)) != b)
1150 {
1151 num2 = 2;
1152 }
1153 else if ((b2 = (byte)(num >> 8)) != b)
1154 {
1155 num2 = 1;
1156 }
1157 else
1158 {
1159 b2 = (byte)num;
1160 num2 = 0;
1161 }
1162 bool flag = (b2 & 0x80) != (b & 0x80) && !isUnsigned;
1163 int num3 = num2 + 1 + (flag ? 1 : 0);
1164 if (bits != null)
1165 {
1166 num3 = checked(4 * (bits.Length - 1) + num3);
1167 }
1168 byte[] result;
1169 switch (mode)
1170 {
1171 case GetBytesMode.AllocateArray:
1172 destination = (result = new byte[num3]);
1173 break;
1174 case GetBytesMode.Count:
1175 bytesWritten = num3;
1176 return null;
1177 default:
1178 bytesWritten = num3;
1179 if (destination.Length < num3)
1180 {
1181 return null;
1182 }
1183 result = s_success;
1184 break;
1185 }
1186 int num4 = (isBigEndian ? (num3 - 1) : 0);
1187 int num5 = ((!isBigEndian) ? 1 : (-1));
1188 if (bits != null)
1189 {
1190 for (int j = 0; j < bits.Length - 1; j++)
1191 {
1192 uint num6 = bits[j];
1193 if (sign == -1)
1194 {
1195 num6 = ~num6;
1196 if (j <= i)
1197 {
1198 num6++;
1199 }
1200 }
1201 destination[num4] = (byte)num6;
1202 num4 += num5;
1203 destination[num4] = (byte)(num6 >> 8);
1204 num4 += num5;
1205 destination[num4] = (byte)(num6 >> 16);
1206 num4 += num5;
1207 destination[num4] = (byte)(num6 >> 24);
1208 num4 += num5;
1209 }
1210 }
1211 destination[num4] = (byte)num;
1212 if (num2 != 0)
1213 {
1214 num4 += num5;
1215 destination[num4] = (byte)(num >> 8);
1216 if (num2 != 1)
1217 {
1218 num4 += num5;
1219 destination[num4] = (byte)(num >> 16);
1220 if (num2 != 2)
1221 {
1222 num4 += num5;
1223 destination[num4] = (byte)(num >> 24);
1224 }
1225 }
1226 }
1227 if (flag)
1228 {
1229 num4 += num5;
1230 destination[num4] = b;
1231 }
1232 return result;
1233 }
1234
1236 {
1237 if (_bits == null && _sign == 0)
1238 {
1239 scratch[0] = 0u;
1240 return scratch.Slice(0, 1);
1241 }
1242 Span<uint> span = scratch;
1243 bool flag = true;
1244 uint num;
1245 if (_bits == null)
1246 {
1247 span[0] = (uint)_sign;
1248 span = span.Slice(0, 1);
1249 num = ((_sign < 0) ? uint.MaxValue : 0u);
1250 }
1251 else if (_sign == -1)
1252 {
1253 if (span.Length >= _bits.Length)
1254 {
1255 _bits.AsSpan().CopyTo(span);
1256 span = span.Slice(0, _bits.Length);
1257 }
1258 else
1259 {
1260 span = (uint[])_bits.Clone();
1261 }
1263 num = uint.MaxValue;
1264 }
1265 else
1266 {
1267 span = _bits;
1268 num = 0u;
1269 flag = false;
1270 }
1271 int num2 = span.Length - 1;
1272 while (num2 > 0 && span[num2] == num)
1273 {
1274 num2--;
1275 }
1276 bool flag2 = (span[num2] & 0x80000000u) != (num & 0x80000000u);
1277 int num3 = num2 + 1 + (flag2 ? 1 : 0);
1278 bool flag3 = true;
1279 if (num3 <= scratch.Length)
1280 {
1281 scratch = scratch.Slice(0, num3);
1282 flag3 = !flag;
1283 }
1284 else
1285 {
1286 scratch = new uint[num3];
1287 }
1288 if (flag3)
1289 {
1290 span.Slice(0, num2 + 1).CopyTo(scratch);
1291 }
1292 if (flag2)
1293 {
1294 scratch[^1] = num;
1295 }
1296 return scratch;
1297 }
1298
1299 public override string ToString()
1300 {
1302 }
1303
1304 public string ToString(IFormatProvider? provider)
1305 {
1306 return BigNumber.FormatBigInteger(this, null, NumberFormatInfo.GetInstance(provider));
1307 }
1308
1309 public string ToString(string? format)
1310 {
1312 }
1313
1314 public string ToString(string? format, IFormatProvider? provider)
1315 {
1317 }
1318
1319 public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format = default(ReadOnlySpan<char>), IFormatProvider? provider = null)
1320 {
1321 return BigNumber.TryFormatBigInteger(this, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten);
1322 }
1323
1324 private static BigInteger Add(uint[] leftBits, int leftSign, uint[] rightBits, int rightSign)
1325 {
1326 bool flag = leftBits == null;
1327 bool flag2 = rightBits == null;
1328 if (flag && flag2)
1329 {
1330 return (long)leftSign + (long)rightSign;
1331 }
1332 if (flag)
1333 {
1334 uint[] array = BigIntegerCalculator.Add(rightBits, NumericsHelpers.Abs(leftSign));
1335 return new BigInteger(array, array, leftSign < 0);
1336 }
1337 if (flag2)
1338 {
1339 uint[] array2 = BigIntegerCalculator.Add(leftBits, NumericsHelpers.Abs(rightSign));
1340 return new BigInteger(array2, array2, leftSign < 0);
1341 }
1342 if (leftBits.Length < rightBits.Length)
1343 {
1344 uint[] array3 = BigIntegerCalculator.Add(rightBits, leftBits);
1345 return new BigInteger(array3, array3, leftSign < 0);
1346 }
1347 uint[] array4 = BigIntegerCalculator.Add(leftBits, rightBits);
1348 return new BigInteger(array4, array4, leftSign < 0);
1349 }
1350
1351 public static BigInteger operator -(BigInteger left, BigInteger right)
1352 {
1353 if (left._sign < 0 != right._sign < 0)
1354 {
1355 return Add(left._bits, left._sign, right._bits, -1 * right._sign);
1356 }
1357 return Subtract(left._bits, left._sign, right._bits, right._sign);
1358 }
1359
1360 private static BigInteger Subtract(uint[] leftBits, int leftSign, uint[] rightBits, int rightSign)
1361 {
1362 bool flag = leftBits == null;
1363 bool flag2 = rightBits == null;
1364 if (flag && flag2)
1365 {
1366 return (long)leftSign - (long)rightSign;
1367 }
1368 if (flag)
1369 {
1370 uint[] array = BigIntegerCalculator.Subtract(rightBits, NumericsHelpers.Abs(leftSign));
1371 return new BigInteger(array, array, leftSign >= 0);
1372 }
1373 if (flag2)
1374 {
1375 uint[] array2 = BigIntegerCalculator.Subtract(leftBits, NumericsHelpers.Abs(rightSign));
1376 return new BigInteger(array2, array2, leftSign < 0);
1377 }
1378 if (BigIntegerCalculator.Compare(leftBits, rightBits) < 0)
1379 {
1380 uint[] array3 = BigIntegerCalculator.Subtract(rightBits, leftBits);
1381 return new BigInteger(array3, array3, leftSign >= 0);
1382 }
1383 uint[] array4 = BigIntegerCalculator.Subtract(leftBits, rightBits);
1384 return new BigInteger(array4, array4, leftSign < 0);
1385 }
1386
1387 public static implicit operator BigInteger(byte value)
1388 {
1389 return new BigInteger(value);
1390 }
1391
1392 [CLSCompliant(false)]
1393 public static implicit operator BigInteger(sbyte value)
1394 {
1395 return new BigInteger(value);
1396 }
1397
1398 public static implicit operator BigInteger(short value)
1399 {
1400 return new BigInteger(value);
1401 }
1402
1403 [CLSCompliant(false)]
1404 public static implicit operator BigInteger(ushort value)
1405 {
1406 return new BigInteger(value);
1407 }
1408
1409 public static implicit operator BigInteger(int value)
1410 {
1411 return new BigInteger(value);
1412 }
1413
1414 [CLSCompliant(false)]
1415 public static implicit operator BigInteger(uint value)
1416 {
1417 return new BigInteger(value);
1418 }
1419
1420 public static implicit operator BigInteger(long value)
1421 {
1422 return new BigInteger(value);
1423 }
1424
1425 [CLSCompliant(false)]
1426 public static implicit operator BigInteger(ulong value)
1427 {
1428 return new BigInteger(value);
1429 }
1430
1431 public static explicit operator BigInteger(float value)
1432 {
1433 return new BigInteger(value);
1434 }
1435
1436 public static explicit operator BigInteger(double value)
1437 {
1438 return new BigInteger(value);
1439 }
1440
1441 public static explicit operator BigInteger(decimal value)
1442 {
1443 return new BigInteger(value);
1444 }
1445
1446 public static explicit operator byte(BigInteger value)
1447 {
1448 return checked((byte)(int)value);
1449 }
1450
1451 [CLSCompliant(false)]
1452 public static explicit operator sbyte(BigInteger value)
1453 {
1454 return checked((sbyte)(int)value);
1455 }
1456
1457 public static explicit operator short(BigInteger value)
1458 {
1459 return checked((short)(int)value);
1460 }
1461
1462 [CLSCompliant(false)]
1463 public static explicit operator ushort(BigInteger value)
1464 {
1465 return checked((ushort)(int)value);
1466 }
1467
1468 public static explicit operator int(BigInteger value)
1469 {
1470 if (value._bits == null)
1471 {
1472 return value._sign;
1473 }
1474 if (value._bits.Length > 1)
1475 {
1477 }
1478 if (value._sign > 0)
1479 {
1480 return checked((int)value._bits[0]);
1481 }
1482 if (value._bits[0] > 2147483648u)
1483 {
1485 }
1486 return (int)(0 - value._bits[0]);
1487 }
1488
1489 [CLSCompliant(false)]
1490 public static explicit operator uint(BigInteger value)
1491 {
1492 if (value._bits == null)
1493 {
1494 return checked((uint)value._sign);
1495 }
1496 if (value._bits.Length > 1 || value._sign < 0)
1497 {
1499 }
1500 return value._bits[0];
1501 }
1502
1503 public static explicit operator long(BigInteger value)
1504 {
1505 if (value._bits == null)
1506 {
1507 return value._sign;
1508 }
1509 int num = value._bits.Length;
1510 if (num > 2)
1511 {
1513 }
1514 ulong num2 = ((num <= 1) ? value._bits[0] : NumericsHelpers.MakeUlong(value._bits[1], value._bits[0]));
1515 long num3 = (long)((value._sign > 0) ? num2 : (0L - num2));
1516 if ((num3 > 0 && value._sign > 0) || (num3 < 0 && value._sign < 0))
1517 {
1518 return num3;
1519 }
1521 }
1522
1523 [CLSCompliant(false)]
1524 public static explicit operator ulong(BigInteger value)
1525 {
1526 if (value._bits == null)
1527 {
1528 return checked((ulong)value._sign);
1529 }
1530 int num = value._bits.Length;
1531 if (num > 2 || value._sign < 0)
1532 {
1534 }
1535 if (num > 1)
1536 {
1537 return NumericsHelpers.MakeUlong(value._bits[1], value._bits[0]);
1538 }
1539 return value._bits[0];
1540 }
1541
1542 public static explicit operator float(BigInteger value)
1543 {
1544 return (float)(double)value;
1545 }
1546
1547 public static explicit operator double(BigInteger value)
1548 {
1549 int sign = value._sign;
1550 uint[] bits = value._bits;
1551 if (bits == null)
1552 {
1553 return sign;
1554 }
1555 int num = bits.Length;
1556 if (num > 32)
1557 {
1558 if (sign == 1)
1559 {
1560 return double.PositiveInfinity;
1561 }
1562 return double.NegativeInfinity;
1563 }
1564 ulong num2 = bits[num - 1];
1565 ulong num3 = ((num > 1) ? bits[num - 2] : 0u);
1566 ulong num4 = ((num > 2) ? bits[num - 3] : 0u);
1567 int num5 = NumericsHelpers.CbitHighZero((uint)num2);
1568 int exp = (num - 2) * 32 - num5;
1569 ulong man = (num2 << 32 + num5) | (num3 << num5) | (num4 >> 32 - num5);
1570 return NumericsHelpers.GetDoubleFromParts(sign, exp, man);
1571 }
1572
1573 public static explicit operator decimal(BigInteger value)
1574 {
1575 if (value._bits == null)
1576 {
1577 return value._sign;
1578 }
1579 int num = value._bits.Length;
1580 if (num > 3)
1581 {
1583 }
1584 int lo = 0;
1585 int mid = 0;
1586 int hi = 0;
1587 if (num > 2)
1588 {
1589 hi = (int)value._bits[2];
1590 }
1591 if (num > 1)
1592 {
1593 mid = (int)value._bits[1];
1594 }
1595 if (num > 0)
1596 {
1597 lo = (int)value._bits[0];
1598 }
1599 return new decimal(lo, mid, hi, value._sign < 0, 0);
1600 }
1601
1602 public static BigInteger operator &(BigInteger left, BigInteger right)
1603 {
1604 if (left.IsZero || right.IsZero)
1605 {
1606 return Zero;
1607 }
1608 if (left._bits == null && right._bits == null)
1609 {
1610 return left._sign & right._sign;
1611 }
1612 Span<uint> scratch = stackalloc uint[32];
1613 ReadOnlySpan<uint> readOnlySpan = left.ToUInt32Span(scratch);
1614 scratch = stackalloc uint[32];
1615 ReadOnlySpan<uint> readOnlySpan2 = right.ToUInt32Span(scratch);
1616 uint[] array = new uint[Math.Max(readOnlySpan.Length, readOnlySpan2.Length)];
1617 uint num = ((left._sign < 0) ? uint.MaxValue : 0u);
1618 uint num2 = ((right._sign < 0) ? uint.MaxValue : 0u);
1619 for (int i = 0; i < array.Length; i++)
1620 {
1621 uint num3 = ((i < readOnlySpan.Length) ? readOnlySpan[i] : num);
1622 uint num4 = ((i < readOnlySpan2.Length) ? readOnlySpan2[i] : num2);
1623 array[i] = num3 & num4;
1624 }
1625 return new BigInteger(array);
1626 }
1627
1628 public static BigInteger operator |(BigInteger left, BigInteger right)
1629 {
1630 if (left.IsZero)
1631 {
1632 return right;
1633 }
1634 if (right.IsZero)
1635 {
1636 return left;
1637 }
1638 if (left._bits == null && right._bits == null)
1639 {
1640 return left._sign | right._sign;
1641 }
1642 Span<uint> scratch = stackalloc uint[32];
1643 ReadOnlySpan<uint> readOnlySpan = left.ToUInt32Span(scratch);
1644 scratch = stackalloc uint[32];
1645 ReadOnlySpan<uint> readOnlySpan2 = right.ToUInt32Span(scratch);
1646 uint[] array = new uint[Math.Max(readOnlySpan.Length, readOnlySpan2.Length)];
1647 uint num = ((left._sign < 0) ? uint.MaxValue : 0u);
1648 uint num2 = ((right._sign < 0) ? uint.MaxValue : 0u);
1649 for (int i = 0; i < array.Length; i++)
1650 {
1651 uint num3 = ((i < readOnlySpan.Length) ? readOnlySpan[i] : num);
1652 uint num4 = ((i < readOnlySpan2.Length) ? readOnlySpan2[i] : num2);
1653 array[i] = num3 | num4;
1654 }
1655 return new BigInteger(array);
1656 }
1657
1658 public static BigInteger operator ^(BigInteger left, BigInteger right)
1659 {
1660 if (left._bits == null && right._bits == null)
1661 {
1662 return left._sign ^ right._sign;
1663 }
1664 Span<uint> scratch = stackalloc uint[32];
1665 ReadOnlySpan<uint> readOnlySpan = left.ToUInt32Span(scratch);
1666 scratch = stackalloc uint[32];
1667 ReadOnlySpan<uint> readOnlySpan2 = right.ToUInt32Span(scratch);
1668 uint[] array = new uint[Math.Max(readOnlySpan.Length, readOnlySpan2.Length)];
1669 uint num = ((left._sign < 0) ? uint.MaxValue : 0u);
1670 uint num2 = ((right._sign < 0) ? uint.MaxValue : 0u);
1671 for (int i = 0; i < array.Length; i++)
1672 {
1673 uint num3 = ((i < readOnlySpan.Length) ? readOnlySpan[i] : num);
1674 uint num4 = ((i < readOnlySpan2.Length) ? readOnlySpan2[i] : num2);
1675 array[i] = num3 ^ num4;
1676 }
1677 return new BigInteger(array);
1678 }
1679
1680 public static BigInteger operator <<(BigInteger value, int shift)
1681 {
1682 if (shift == 0)
1683 {
1684 return value;
1685 }
1686 if (shift == int.MinValue)
1687 {
1688 return value >> int.MaxValue >> 1;
1689 }
1690 if (shift < 0)
1691 {
1692 return value >> -shift;
1693 }
1694 (int Quotient, int Remainder) tuple = Math.DivRem(shift, 32);
1695 int item = tuple.Quotient;
1696 int item2 = tuple.Remainder;
1697 Span<uint> span = stackalloc uint[1];
1698 Span<uint> xd = span;
1699 bool partsForBitManipulation = GetPartsForBitManipulation(ref value, ref xd);
1700 int num = xd.Length + item + 1;
1701 uint[] valueArray = null;
1702 Span<uint> span2 = default(Span<uint>);
1703 if (num <= 64)
1704 {
1705 span = stackalloc uint[64];
1706 span2 = span.Slice(0, num);
1707 span = span2.Slice(0, item);
1708 span.Clear();
1709 }
1710 else
1711 {
1712 span2 = (valueArray = new uint[num]);
1713 }
1714 uint num2 = 0u;
1715 if (item2 == 0)
1716 {
1717 for (int i = 0; i < xd.Length; i++)
1718 {
1719 span2[i + item] = xd[i];
1720 }
1721 }
1722 else
1723 {
1724 int num3 = 32 - item2;
1725 for (int j = 0; j < xd.Length; j++)
1726 {
1727 uint num4 = xd[j];
1728 span2[j + item] = (num4 << item2) | num2;
1729 num2 = num4 >> num3;
1730 }
1731 }
1732 span2[^1] = num2;
1733 return new BigInteger(span2, valueArray, partsForBitManipulation);
1734 }
1735
1736 public static BigInteger operator >>(BigInteger value, int shift)
1737 {
1738 if (shift == 0)
1739 {
1740 return value;
1741 }
1742 if (shift == int.MinValue)
1743 {
1744 return value << int.MaxValue << 1;
1745 }
1746 if (shift < 0)
1747 {
1748 return value << -shift;
1749 }
1750 (int Quotient, int Remainder) tuple = Math.DivRem(shift, 32);
1751 int item = tuple.Quotient;
1752 int item2 = tuple.Remainder;
1753 Span<uint> span = stackalloc uint[1];
1754 Span<uint> span2 = span;
1755 Span<uint> xd = span2;
1756 bool partsForBitManipulation = GetPartsForBitManipulation(ref value, ref xd);
1757 bool flag = false;
1758 if (partsForBitManipulation)
1759 {
1760 if (shift >= 32 * xd.Length)
1761 {
1762 return MinusOne;
1763 }
1764 if (xd != span2)
1765 {
1766 if (xd.Length <= 64)
1767 {
1768 span = stackalloc uint[64];
1769 span2 = span.Slice(0, xd.Length);
1770 xd.CopyTo(span2);
1771 xd = span2;
1772 }
1773 else
1774 {
1775 xd = xd.ToArray();
1776 }
1777 }
1779 flag = item2 == 0 && xd[^1] == 0;
1780 }
1781 int num = xd.Length - item + (flag ? 1 : 0);
1782 uint[] valueArray = null;
1783 Span<uint> span3 = default(Span<uint>);
1784 if (num > 0)
1785 {
1786 Span<uint> span4;
1787 if (num <= 64)
1788 {
1789 span = stackalloc uint[64];
1790 span4 = span.Slice(0, num);
1791 }
1792 else
1793 {
1794 span4 = (valueArray = new uint[num]);
1795 }
1796 span3 = span4;
1797 }
1798 if (item2 == 0)
1799 {
1800 for (int num2 = xd.Length - 1; num2 >= item; num2--)
1801 {
1802 span3[num2 - item] = xd[num2];
1803 }
1804 }
1805 else
1806 {
1807 int num3 = 32 - item2;
1808 uint num4 = 0u;
1809 for (int num5 = xd.Length - 1; num5 >= item; num5--)
1810 {
1811 uint num6 = xd[num5];
1812 if (partsForBitManipulation && num5 == xd.Length - 1)
1813 {
1814 span3[num5 - item] = (num6 >> item2) | (uint)(-1 << num3);
1815 }
1816 else
1817 {
1818 span3[num5 - item] = (num6 >> item2) | num4;
1819 }
1820 num4 = num6 << num3;
1821 }
1822 }
1823 if (partsForBitManipulation)
1824 {
1825 if (flag)
1826 {
1827 span3[^1] = uint.MaxValue;
1828 }
1830 }
1831 return new BigInteger(span3, valueArray, partsForBitManipulation);
1832 }
1833
1835 {
1836 return -(value + One);
1837 }
1838
1840 {
1841 return new BigInteger(-value._sign, value._bits);
1842 }
1843
1845 {
1846 return value;
1847 }
1848
1850 {
1851 return value + One;
1852 }
1853
1855 {
1856 return value - One;
1857 }
1858
1859 public static BigInteger operator +(BigInteger left, BigInteger right)
1860 {
1861 if (left._sign < 0 != right._sign < 0)
1862 {
1863 return Subtract(left._bits, left._sign, right._bits, -1 * right._sign);
1864 }
1865 return Add(left._bits, left._sign, right._bits, right._sign);
1866 }
1867
1868 public static BigInteger operator *(BigInteger left, BigInteger right)
1869 {
1870 bool flag = left._bits == null;
1871 bool flag2 = right._bits == null;
1872 if (flag && flag2)
1873 {
1874 return (long)left._sign * (long)right._sign;
1875 }
1876 if (flag)
1877 {
1879 return new BigInteger(array, array, (left._sign < 0) ^ (right._sign < 0));
1880 }
1881 if (flag2)
1882 {
1883 uint[] array2 = BigIntegerCalculator.Multiply(left._bits, NumericsHelpers.Abs(right._sign));
1884 return new BigInteger(array2, array2, (left._sign < 0) ^ (right._sign < 0));
1885 }
1886 if (left._bits == right._bits)
1887 {
1888 uint[] array3 = BigIntegerCalculator.Square(left._bits);
1889 return new BigInteger(array3, array3, (left._sign < 0) ^ (right._sign < 0));
1890 }
1891 if (left._bits.Length < right._bits.Length)
1892 {
1893 uint[] array4 = BigIntegerCalculator.Multiply(right._bits, left._bits);
1894 return new BigInteger(array4, array4, (left._sign < 0) ^ (right._sign < 0));
1895 }
1896 uint[] array5 = BigIntegerCalculator.Multiply(left._bits, right._bits);
1897 return new BigInteger(array5, array5, (left._sign < 0) ^ (right._sign < 0));
1898 }
1899
1900 public static BigInteger operator /(BigInteger dividend, BigInteger divisor)
1901 {
1902 bool flag = dividend._bits == null;
1903 bool flag2 = divisor._bits == null;
1904 if (flag && flag2)
1905 {
1906 return dividend._sign / divisor._sign;
1907 }
1908 if (flag)
1909 {
1910 return s_bnZeroInt;
1911 }
1912 if (flag2)
1913 {
1914 uint[] array = BigIntegerCalculator.Divide(dividend._bits, NumericsHelpers.Abs(divisor._sign));
1915 return new BigInteger(array, array, (dividend._sign < 0) ^ (divisor._sign < 0));
1916 }
1917 if (dividend._bits.Length < divisor._bits.Length)
1918 {
1919 return s_bnZeroInt;
1920 }
1921 uint[] array2 = BigIntegerCalculator.Divide(dividend._bits, divisor._bits);
1922 return new BigInteger(array2, array2, (dividend._sign < 0) ^ (divisor._sign < 0));
1923 }
1924
1925 public static BigInteger operator %(BigInteger dividend, BigInteger divisor)
1926 {
1927 bool flag = dividend._bits == null;
1928 bool flag2 = divisor._bits == null;
1929 if (flag && flag2)
1930 {
1931 return dividend._sign % divisor._sign;
1932 }
1933 if (flag)
1934 {
1935 return dividend;
1936 }
1937 if (flag2)
1938 {
1939 uint num = BigIntegerCalculator.Remainder(dividend._bits, NumericsHelpers.Abs(divisor._sign));
1940 return (dividend._sign < 0) ? (-1 * num) : num;
1941 }
1942 if (dividend._bits.Length < divisor._bits.Length)
1943 {
1944 return dividend;
1945 }
1946 uint[] array = BigIntegerCalculator.Remainder(dividend._bits, divisor._bits);
1947 return new BigInteger(array, array, dividend._sign < 0);
1948 }
1949
1950 public static bool operator <(BigInteger left, BigInteger right)
1951 {
1952 return left.CompareTo(right) < 0;
1953 }
1954
1955 public static bool operator <=(BigInteger left, BigInteger right)
1956 {
1957 return left.CompareTo(right) <= 0;
1958 }
1959
1960 public static bool operator >(BigInteger left, BigInteger right)
1961 {
1962 return left.CompareTo(right) > 0;
1963 }
1964
1965 public static bool operator >=(BigInteger left, BigInteger right)
1966 {
1967 return left.CompareTo(right) >= 0;
1968 }
1969
1970 public static bool operator ==(BigInteger left, BigInteger right)
1971 {
1972 return left.Equals(right);
1973 }
1974
1975 public static bool operator !=(BigInteger left, BigInteger right)
1976 {
1977 return !left.Equals(right);
1978 }
1979
1980 public static bool operator <(BigInteger left, long right)
1981 {
1982 return left.CompareTo(right) < 0;
1983 }
1984
1985 public static bool operator <=(BigInteger left, long right)
1986 {
1987 return left.CompareTo(right) <= 0;
1988 }
1989
1990 public static bool operator >(BigInteger left, long right)
1991 {
1992 return left.CompareTo(right) > 0;
1993 }
1994
1995 public static bool operator >=(BigInteger left, long right)
1996 {
1997 return left.CompareTo(right) >= 0;
1998 }
1999
2000 public static bool operator ==(BigInteger left, long right)
2001 {
2002 return left.Equals(right);
2003 }
2004
2005 public static bool operator !=(BigInteger left, long right)
2006 {
2007 return !left.Equals(right);
2008 }
2009
2010 public static bool operator <(long left, BigInteger right)
2011 {
2012 return right.CompareTo(left) > 0;
2013 }
2014
2015 public static bool operator <=(long left, BigInteger right)
2016 {
2017 return right.CompareTo(left) >= 0;
2018 }
2019
2020 public static bool operator >(long left, BigInteger right)
2021 {
2022 return right.CompareTo(left) < 0;
2023 }
2024
2025 public static bool operator >=(long left, BigInteger right)
2026 {
2027 return right.CompareTo(left) <= 0;
2028 }
2029
2030 public static bool operator ==(long left, BigInteger right)
2031 {
2032 return right.Equals(left);
2033 }
2034
2035 public static bool operator !=(long left, BigInteger right)
2036 {
2037 return !right.Equals(left);
2038 }
2039
2040 [CLSCompliant(false)]
2041 public static bool operator <(BigInteger left, ulong right)
2042 {
2043 return left.CompareTo(right) < 0;
2044 }
2045
2046 [CLSCompliant(false)]
2047 public static bool operator <=(BigInteger left, ulong right)
2048 {
2049 return left.CompareTo(right) <= 0;
2050 }
2051
2052 [CLSCompliant(false)]
2053 public static bool operator >(BigInteger left, ulong right)
2054 {
2055 return left.CompareTo(right) > 0;
2056 }
2057
2058 [CLSCompliant(false)]
2059 public static bool operator >=(BigInteger left, ulong right)
2060 {
2061 return left.CompareTo(right) >= 0;
2062 }
2063
2064 [CLSCompliant(false)]
2065 public static bool operator ==(BigInteger left, ulong right)
2066 {
2067 return left.Equals(right);
2068 }
2069
2070 [CLSCompliant(false)]
2071 public static bool operator !=(BigInteger left, ulong right)
2072 {
2073 return !left.Equals(right);
2074 }
2075
2076 [CLSCompliant(false)]
2077 public static bool operator <(ulong left, BigInteger right)
2078 {
2079 return right.CompareTo(left) > 0;
2080 }
2081
2082 [CLSCompliant(false)]
2083 public static bool operator <=(ulong left, BigInteger right)
2084 {
2085 return right.CompareTo(left) >= 0;
2086 }
2087
2088 [CLSCompliant(false)]
2089 public static bool operator >(ulong left, BigInteger right)
2090 {
2091 return right.CompareTo(left) < 0;
2092 }
2093
2094 [CLSCompliant(false)]
2095 public static bool operator >=(ulong left, BigInteger right)
2096 {
2097 return right.CompareTo(left) <= 0;
2098 }
2099
2100 [CLSCompliant(false)]
2101 public static bool operator ==(ulong left, BigInteger right)
2102 {
2103 return right.Equals(left);
2104 }
2105
2106 [CLSCompliant(false)]
2107 public static bool operator !=(ulong left, BigInteger right)
2108 {
2109 return !right.Equals(left);
2110 }
2111
2112 public long GetBitLength()
2113 {
2114 int sign = _sign;
2115 uint[] bits = _bits;
2116 int num;
2117 uint num2;
2118 if (bits == null)
2119 {
2120 num = 1;
2121 num2 = (uint)((sign < 0) ? (-sign) : sign);
2122 }
2123 else
2124 {
2125 num = bits.Length;
2126 num2 = bits[num - 1];
2127 }
2128 long num3 = (long)num * 32L - BitOperations.LeadingZeroCount(num2);
2129 if (sign >= 0)
2130 {
2131 return num3;
2132 }
2133 if ((num2 & (num2 - 1)) != 0)
2134 {
2135 return num3;
2136 }
2137 for (int num4 = num - 2; num4 >= 0; num4--)
2138 {
2139 if (bits[num4] != 0)
2140 {
2141 return num3;
2142 }
2143 }
2144 return num3 - 1;
2145 }
2146
2147 private static bool GetPartsForBitManipulation(ref BigInteger x, ref Span<uint> xd)
2148 {
2149 if (x._bits == null)
2150 {
2151 xd[0] = (uint)((x._sign < 0) ? (-x._sign) : x._sign);
2152 }
2153 else
2154 {
2155 xd = x._bits;
2156 }
2157 return x._sign < 0;
2158 }
2159
2160 internal static int GetDiffLength(uint[] rgu1, uint[] rgu2, int cu)
2161 {
2162 int num = cu;
2163 while (--num >= 0)
2164 {
2165 if (rgu1[num] != rgu2[num])
2166 {
2167 return num + 1;
2168 }
2169 }
2170 return 0;
2171 }
2172}
static unsafe void Copy(Array sourceArray, Array destinationArray, int length)
Definition Array.cs:624
static NumberFormatInfo GetInstance(IFormatProvider? formatProvider)
const double E
Definition Math.cs:14
static double Log(double d)
static int DivRem(int a, int b, out int result)
Definition Math.cs:329
static byte Max(byte val1, byte val2)
Definition Math.cs:738
static uint[] Divide(uint[] left, uint right, out uint remainder)
static uint Gcd(uint left, uint right)
static uint[] Pow(uint value, uint power)
static uint[] Add(uint[] left, uint right)
static uint[] Multiply(uint[] left, uint right)
static uint[] Subtract(uint[] left, uint right)
static uint Remainder(uint[] left, uint right)
static unsafe uint[] Square(uint[] value)
static int Compare(uint[] left, uint[] right)
static bool TryParseBigInteger(string value, NumberStyles style, NumberFormatInfo info, out BigInteger result)
Definition BigNumber.cs:47
static BigInteger ParseBigInteger(string value, NumberStyles style, NumberFormatInfo info)
Definition BigNumber.cs:76
static string FormatBigInteger(BigInteger value, string format, NumberFormatInfo info)
Definition BigNumber.cs:420
static bool TryFormatBigInteger(BigInteger value, ReadOnlySpan< char > format, NumberFormatInfo info, Span< char > destination, out int charsWritten)
Definition BigNumber.cs:427
static int LeadingZeroCount(uint value)
static uint CombineHash(uint u1, uint u2)
static double GetDoubleFromParts(int sign, int exp, ulong man)
static void GetDoubleParts(double dbl, out int sign, out int exp, out ulong man, out bool fFinite)
static ulong MakeUlong(uint uHi, uint uLo)
static void DangerousMakeTwosComplement(Span< uint > d)
static string Overflow_NotANumber
Definition SR.cs:28
static string Overflow_Int32
Definition SR.cs:1772
static string Overflow_UInt64
Definition SR.cs:1790
static string Overflow_BigIntInfinity
Definition SR.cs:26
static string ArgumentOutOfRange_MustBeNonNeg
Definition SR.cs:24
static string Overflow_Int64
Definition SR.cs:1774
static string Overflow_Negative_Unsigned
Definition SR.cs:42
static string Argument_MustBeBigInt
Definition SR.cs:20
static string Overflow_Decimal
Definition SR.cs:1766
static string Overflow_UInt32
Definition SR.cs:1788
Definition SR.cs:7
int CompareTo(ulong other)
static bool TryParse(ReadOnlySpan< char > value, out BigInteger result)
bool TryWriteOrCountBytes(Span< byte > destination, out int bytesWritten, bool isUnsigned=false, bool isBigEndian=false)
static BigInteger operator/(BigInteger dividend, BigInteger divisor)
static bool operator<(BigInteger left, BigInteger right)
static BigInteger ModPow(BigInteger value, BigInteger exponent, BigInteger modulus)
bool TryFormat(Span< char > destination, out int charsWritten, ReadOnlySpan< char > format=default(ReadOnlySpan< char >), IFormatProvider? provider=null)
static BigInteger Divide(BigInteger dividend, BigInteger divisor)
static BigInteger operator|(BigInteger left, BigInteger right)
static BigInteger Subtract(BigInteger left, BigInteger right)
static bool operator!=(BigInteger left, BigInteger right)
static BigInteger operator*(BigInteger left, BigInteger right)
byte[] TryGetBytes(GetBytesMode mode, Span< byte > destination, bool isUnsigned, bool isBigEndian, ref int bytesWritten)
static readonly BigInteger s_bnMinusOneInt
Definition BigInteger.cs:28
static BigInteger Parse(string value)
static BigInteger DivRem(BigInteger dividend, BigInteger divisor, out BigInteger remainder)
static readonly BigInteger s_bnOneInt
Definition BigInteger.cs:24
static bool operator<=(BigInteger left, BigInteger right)
int CompareTo(object? obj)
int CompareTo(BigInteger other)
static BigInteger Parse(ReadOnlySpan< char > value, NumberStyles style=NumberStyles.Integer, IFormatProvider? provider=null)
byte[] ToByteArray(bool isUnsigned=false, bool isBigEndian=false)
readonly uint[] _bits
Definition BigInteger.cs:20
static double Log10(BigInteger value)
static BigInteger operator<<(BigInteger value, int shift)
static BigInteger Abs(BigInteger value)
static double Log(BigInteger value, double baseValue)
int GetByteCount(bool isUnsigned=false)
static int Compare(BigInteger left, BigInteger right)
bool Equals(BigInteger other)
static readonly BigInteger s_bnZeroInt
Definition BigInteger.cs:26
static BigInteger GreatestCommonDivisor(uint[] leftBits, uint[] rightBits)
static BigInteger Pow(BigInteger value, int exponent)
static bool GetPartsForBitManipulation(ref BigInteger x, ref Span< uint > xd)
override int GetHashCode()
static bool operator>(BigInteger left, BigInteger right)
override string ToString()
static double Log(BigInteger value)
static bool operator==(BigInteger left, BigInteger right)
static BigInteger operator~(BigInteger value)
static BigInteger operator+(BigInteger value)
static readonly BigInteger s_bnMinInt
Definition BigInteger.cs:22
static BigInteger operator--(BigInteger value)
static BigInteger Multiply(BigInteger left, BigInteger right)
static bool TryParse([NotNullWhen(true)] string? value, NumberStyles style, IFormatProvider? provider, out BigInteger result)
static BigInteger GreatestCommonDivisor(BigInteger left, BigInteger right)
BigInteger(decimal value)
static BigInteger operator++(BigInteger value)
string ToString(string? format)
static BigInteger operator%(BigInteger dividend, BigInteger divisor)
override bool Equals([NotNullWhen(true)] object? obj)
static bool operator>=(BigInteger left, BigInteger right)
static BigInteger Parse(string value, NumberStyles style)
static BigInteger operator^(BigInteger left, BigInteger right)
string ToString(IFormatProvider? provider)
BigInteger(ReadOnlySpan< byte > value, bool isUnsigned=false, bool isBigEndian=false)
bool Equals(ulong other)
bool Equals(long other)
static readonly byte[] s_success
Definition BigInteger.cs:30
static bool TryParse(ReadOnlySpan< char > value, NumberStyles style, IFormatProvider? provider, out BigInteger result)
static BigInteger Parse(string value, NumberStyles style, IFormatProvider? provider)
static BigInteger MinusOne
Definition BigInteger.cs:36
static BigInteger Negate(BigInteger value)
string ToString(string? format, IFormatProvider? provider)
static BigInteger Add(BigInteger left, BigInteger right)
static BigInteger One
Definition BigInteger.cs:34
static BigInteger operator>>(BigInteger value, int shift)
static BigInteger Add(uint[] leftBits, int leftSign, uint[] rightBits, int rightSign)
static bool TryParse([NotNullWhen(true)] string? value, out BigInteger result)
static BigInteger Parse(string value, IFormatProvider? provider)
BigInteger(int n, uint[] rgu)
static BigInteger operator&(BigInteger left, BigInteger right)
static BigInteger Remainder(BigInteger dividend, BigInteger divisor)
BigInteger(ReadOnlySpan< uint > value, uint[] valueArray, bool negative)
ReadOnlySpan< uint > ToUInt32Span(Span< uint > scratch)
static BigInteger Min(BigInteger left, BigInteger right)
static BigInteger Zero
Definition BigInteger.cs:32
static BigInteger Subtract(uint[] leftBits, int leftSign, uint[] rightBits, int rightSign)
static int GetDiffLength(uint[] rgu1, uint[] rgu2, int cu)
int CompareTo(long other)
static BigInteger operator-(BigInteger left, BigInteger right)
bool TryWriteBytes(Span< byte > destination, out int bytesWritten, bool isUnsigned=false, bool isBigEndian=false)
static BigInteger Max(BigInteger left, BigInteger right)
void CopyTo(Span< T > destination)
Definition Span.cs:224
Span< T > Slice(int start)
Definition Span.cs:271
unsafe void Clear()
Definition Span.cs:198
T[] ToArray()
Definition Span.cs:291
int Length
Definition Span.cs:70