Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
Number.cs
Go to the documentation of this file.
7using System.Text;
9
10namespace System;
11
12internal static class Number
13{
14 [StructLayout(LayoutKind.Sequential, Pack = 1)]
15 internal ref struct BigInteger
16 {
17 private static readonly uint[] s_Pow10UInt32Table = new uint[10] { 1u, 10u, 100u, 1000u, 10000u, 100000u, 1000000u, 10000000u, 100000000u, 1000000000u };
18
19 private static readonly int[] s_Pow10BigNumTableIndices = new int[8] { 0, 2, 5, 10, 18, 33, 61, 116 };
20
21 private static readonly uint[] s_Pow10BigNumTable = new uint[233]
22 {
23 1u, 100000000u, 2u, 1874919424u, 2328306u, 4u, 0u, 2242703233u, 762134875u, 1262u,
24 7u, 0u, 0u, 3211403009u, 1849224548u, 3668416493u, 3913284084u, 1593091u, 14u, 0u,
25 0u, 0u, 0u, 781532673u, 64985353u, 253049085u, 594863151u, 3553621484u, 3288652808u, 3167596762u,
26 2788392729u, 3911132675u, 590u, 27u, 0u, 0u, 0u, 0u, 0u, 0u,
27 0u, 0u, 2553183233u, 3201533787u, 3638140786u, 303378311u, 1809731782u, 3477761648u, 3583367183u, 649228654u,
28 2915460784u, 487929380u, 1011012442u, 1677677582u, 3428152256u, 1710878487u, 1438394610u, 2161952759u, 4100910556u, 1608314830u,
29 349175u, 54u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
30 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4234999809u, 2012377703u,
31 2408924892u, 1570150255u, 3090844311u, 3273530073u, 1187251475u, 2498123591u, 3364452033u, 1148564857u, 687371067u, 2854068671u,
32 1883165473u, 505794538u, 2988060450u, 3159489326u, 2531348317u, 3215191468u, 849106862u, 3892080979u, 3288073877u, 2242451748u,
33 4183778142u, 2995818208u, 2477501924u, 325481258u, 2487842652u, 1774082830u, 1933815724u, 2962865281u, 1168579910u, 2724829000u,
34 2360374019u, 2315984659u, 2360052375u, 3251779801u, 1664357844u, 28u, 107u, 0u, 0u, 0u,
35 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
36 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
37 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 689565697u,
38 4116392818u, 1853628763u, 516071302u, 2568769159u, 365238920u, 336250165u, 1283268122u, 3425490969u, 248595470u, 2305176814u,
39 2111925499u, 507770399u, 2681111421u, 589114268u, 591287751u, 1708941527u, 4098957707u, 475844916u, 3378731398u, 2452339615u,
40 2817037361u, 2678008327u, 1656645978u, 2383430340u, 73103988u, 448667107u, 2329420453u, 3124020241u, 3625235717u, 3208634035u,
41 2412059158u, 2981664444u, 4117622508u, 838560765u, 3069470027u, 270153238u, 1802868219u, 3692709886u, 2161737865u, 2159912357u,
42 2585798786u, 837488486u, 4237238160u, 2540319504u, 3798629246u, 3748148874u, 1021550776u, 2386715342u, 1973637538u, 1823520457u,
43 1146713475u, 833971519u, 3277251466u, 905620390u, 26278816u, 2680483154u, 2294040859u, 373297482u, 5996609u, 4109575006u,
44 512575049u, 917036550u, 1942311753u, 2816916778u, 3248920332u, 1192784020u, 3537586671u, 2456567643u, 2925660628u, 759380297u,
45 888447942u, 3559939476u, 3654687237u, 805u, 0u, 0u, 0u, 0u, 0u, 0u,
46 0u, 0u, 0u
47 };
48
49 private int _length;
50
51 private unsafe fixed uint _blocks[115];
52
53 public unsafe static void Add(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result)
54 {
55 ref BigInteger reference = ref lhs._length < rhs._length ? ref rhs : ref lhs;
56 ref BigInteger reference2 = ref lhs._length < rhs._length ? ref lhs : ref rhs;
57 int length = reference._length;
58 int length2 = reference2._length;
59 result._length = length;
60 ulong num = 0uL;
61 int num2 = 0;
62 int num3 = 0;
63 int num4 = 0;
64 while (num3 < length2)
65 {
66 ulong num5 = num + reference._blocks[num2] + reference2._blocks[num3];
67 num = num5 >> 32;
68 result._blocks[num4] = (uint)num5;
69 num2++;
70 num3++;
71 num4++;
72 }
73 while (num2 < length)
74 {
75 ulong num6 = num + reference._blocks[num2];
76 num = num6 >> 32;
77 result._blocks[num4] = (uint)num6;
78 num2++;
79 num4++;
80 }
81 if (num != 0L)
82 {
83 result._blocks[num4] = 1u;
84 result._length++;
85 }
86 }
87
88 public unsafe static int Compare(ref BigInteger lhs, ref BigInteger rhs)
89 {
90 int length = lhs._length;
91 int length2 = rhs._length;
92 int num = length - length2;
93 if (num != 0)
94 {
95 return num;
96 }
97 if (length == 0)
98 {
99 return 0;
100 }
101 for (int num2 = length - 1; num2 >= 0; num2--)
102 {
103 long num3 = (long)lhs._blocks[num2] - (long)rhs._blocks[num2];
104 if (num3 != 0L)
105 {
106 if (num3 <= 0)
107 {
108 return -1;
109 }
110 return 1;
111 }
112 }
113 return 0;
114 }
115
116 public static uint CountSignificantBits(uint value)
117 {
118 return (uint)(32 - BitOperations.LeadingZeroCount(value));
119 }
120
121 public static uint CountSignificantBits(ulong value)
122 {
123 return (uint)(64 - BitOperations.LeadingZeroCount(value));
124 }
125
126 public unsafe static uint CountSignificantBits(ref BigInteger value)
127 {
128 if (value.IsZero())
129 {
130 return 0u;
131 }
132 uint num = (uint)(value._length - 1);
133 return num * 32 + CountSignificantBits(value._blocks[num]);
134 }
135
136 public unsafe static void DivRem(ref BigInteger lhs, ref BigInteger rhs, out BigInteger quo, out BigInteger rem)
137 {
138 if (lhs.IsZero())
139 {
140 SetZero(out quo);
141 SetZero(out rem);
142 return;
143 }
144 int length = lhs._length;
145 int length2 = rhs._length;
146 if (length == 1 && length2 == 1)
147 {
148 var (value, value2) = Math.DivRem(lhs._blocks[0], rhs._blocks[0]);
149 SetUInt32(out quo, value);
150 SetUInt32(out rem, value2);
151 return;
152 }
153 if (length2 == 1)
154 {
155 int num = length;
156 ulong right = rhs._blocks[0];
157 ulong num2 = 0uL;
158 for (int num3 = num - 1; num3 >= 0; num3--)
159 {
160 ulong left = (num2 << 32) | lhs._blocks[num3];
161 ulong num4;
162 (num4, num2) = Math.DivRem(left, right);
163 if (num4 == 0L && num3 == num - 1)
164 {
165 num--;
166 }
167 else
168 {
169 quo._blocks[num3] = (uint)num4;
170 }
171 }
172 quo._length = num;
173 SetUInt32(out rem, (uint)num2);
174 return;
175 }
176 if (length2 > length)
177 {
178 SetZero(out quo);
179 SetValue(out rem, ref lhs);
180 return;
181 }
182 int num5 = length - length2 + 1;
183 SetValue(out rem, ref lhs);
184 int num6 = length;
185 uint num7 = rhs._blocks[length2 - 1];
186 uint num8 = rhs._blocks[length2 - 2];
187 int num9 = BitOperations.LeadingZeroCount(num7);
188 int num10 = 32 - num9;
189 if (num9 > 0)
190 {
191 num7 = (num7 << num9) | (num8 >> num10);
192 num8 <<= num9;
193 if (length2 > 2)
194 {
195 num8 |= rhs._blocks[length2 - 3] >> num10;
196 }
197 }
198 for (int num11 = length; num11 >= length2; num11--)
199 {
200 int num12 = num11 - length2;
201 uint num13 = ((num11 < length) ? rem._blocks[num11] : 0u);
202 ulong num14 = ((ulong)num13 << 32) | rem._blocks[num11 - 1];
203 uint num15 = ((num11 > 1) ? rem._blocks[num11 - 2] : 0u);
204 if (num9 > 0)
205 {
206 num14 = (num14 << num9) | (num15 >> num10);
207 num15 <<= num9;
208 if (num11 > 2)
209 {
210 num15 |= rem._blocks[num11 - 3] >> num10;
211 }
212 }
213 ulong num16 = num14 / num7;
214 if (num16 > uint.MaxValue)
215 {
216 num16 = 4294967295uL;
217 }
218 while (DivideGuessTooBig(num16, num14, num15, num7, num8))
219 {
220 num16--;
221 }
222 if (num16 != 0)
223 {
224 uint num17 = SubtractDivisor(ref rem, num12, ref rhs, num16);
225 if (num17 != num13)
226 {
227 num17 = AddDivisor(ref rem, num12, ref rhs);
228 num16--;
229 }
230 }
231 if (num5 != 0)
232 {
233 if (num16 == 0L && num12 == num5 - 1)
234 {
235 num5--;
236 }
237 else
238 {
239 quo._blocks[num12] = (uint)num16;
240 }
241 }
242 if (num11 < num6)
243 {
244 num6--;
245 }
246 }
247 quo._length = num5;
248 for (int num18 = num6 - 1; num18 >= 0; num18--)
249 {
250 if (rem._blocks[num18] == 0)
251 {
252 num6--;
253 }
254 }
255 rem._length = num6;
256 }
257
258 public unsafe static uint HeuristicDivide(ref BigInteger dividend, ref BigInteger divisor)
259 {
260 int num = divisor._length;
261 if (dividend._length < num)
262 {
263 return 0u;
264 }
265 int num2 = num - 1;
266 uint num3 = dividend._blocks[num2] / (divisor._blocks[num2] + 1);
267 if (num3 != 0)
268 {
269 int num4 = 0;
270 ulong num5 = 0uL;
271 ulong num6 = 0uL;
272 do
273 {
274 ulong num7 = (ulong)((long)divisor._blocks[num4] * (long)num3) + num6;
275 num6 = num7 >> 32;
276 ulong num8 = (ulong)((long)dividend._blocks[num4] - (long)(uint)num7) - num5;
277 num5 = (num8 >> 32) & 1;
278 dividend._blocks[num4] = (uint)num8;
279 num4++;
280 }
281 while (num4 < num);
282 while (num > 0 && dividend._blocks[num - 1] == 0)
283 {
284 num--;
285 }
286 dividend._length = num;
287 }
288 if (Compare(ref dividend, ref divisor) >= 0)
289 {
290 num3++;
291 int num9 = 0;
292 ulong num10 = 0uL;
293 do
294 {
295 ulong num11 = (ulong)((long)dividend._blocks[num9] - (long)divisor._blocks[num9]) - num10;
296 num10 = (num11 >> 32) & 1;
297 dividend._blocks[num9] = (uint)num11;
298 num9++;
299 }
300 while (num9 < num);
301 while (num > 0 && dividend._blocks[num - 1] == 0)
302 {
303 num--;
304 }
305 dividend._length = num;
306 }
307 return num3;
308 }
309
310 public unsafe static void Multiply(ref BigInteger lhs, uint value, out BigInteger result)
311 {
312 if (lhs._length <= 1)
313 {
314 SetUInt64(out result, (ulong)lhs.ToUInt32() * (ulong)value);
315 return;
316 }
317 switch (value)
318 {
319 case 0u:
320 SetZero(out result);
321 return;
322 case 1u:
323 SetValue(out result, ref lhs);
324 return;
325 }
326 int length = lhs._length;
327 int i = 0;
328 uint num = 0u;
329 for (; i < length; i++)
330 {
331 ulong num2 = (ulong)((long)lhs._blocks[i] * (long)value + num);
332 result._blocks[i] = (uint)num2;
333 num = (uint)(num2 >> 32);
334 }
335 if (num != 0)
336 {
337 result._blocks[i] = num;
338 result._length = length + 1;
339 }
340 else
341 {
342 result._length = length;
343 }
344 }
345
346 public unsafe static void Multiply(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result)
347 {
348 if (lhs._length <= 1)
349 {
350 Multiply(ref rhs, lhs.ToUInt32(), out result);
351 return;
352 }
353 if (rhs._length <= 1)
354 {
355 Multiply(ref lhs, rhs.ToUInt32(), out result);
356 return;
357 }
358 ref BigInteger reference = ref lhs;
359 int length = lhs._length;
360 ref BigInteger reference2 = ref rhs;
361 int length2 = rhs._length;
362 if (length < length2)
363 {
364 reference = ref rhs;
365 length = rhs._length;
366 reference2 = ref lhs;
367 length2 = lhs._length;
368 }
369 int num = (result._length = length2 + length);
370 result.Clear((uint)num);
371 int num2 = 0;
372 int num3 = 0;
373 while (num2 < length2)
374 {
375 if (reference2._blocks[num2] != 0)
376 {
377 int num4 = 0;
378 int num5 = num3;
379 ulong num6 = 0uL;
380 do
381 {
382 ulong num7 = (ulong)(result._blocks[num5] + (long)reference2._blocks[num2] * (long)reference._blocks[num4]) + num6;
383 num6 = num7 >> 32;
384 result._blocks[num5] = (uint)num7;
385 num5++;
386 num4++;
387 }
388 while (num4 < length);
389 result._blocks[num5] = (uint)num6;
390 }
391 num2++;
392 num3++;
393 }
394 if (num > 0 && result._blocks[num - 1] == 0)
395 {
396 result._length--;
397 }
398 }
399
400 public unsafe static void Pow2(uint exponent, out BigInteger result)
401 {
402 uint remainder;
403 uint num = DivRem32(exponent, out remainder);
404 result._length = (int)(num + 1);
405 if (num != 0)
406 {
407 result.Clear(num);
408 }
409 result._blocks[num] = (uint)(1 << (int)remainder);
410 }
411
412 public unsafe static void Pow10(uint exponent, out BigInteger result)
413 {
414 SetUInt32(out var result2, s_Pow10UInt32Table[exponent & 7]);
415 ref BigInteger reference = ref result2;
416 SetZero(out var result3);
417 ref BigInteger reference2 = ref result3;
418 exponent >>= 3;
419 uint num = 0u;
420 while (exponent != 0)
421 {
422 if ((exponent & (true ? 1u : 0u)) != 0)
423 {
424 fixed (uint* ptr = &s_Pow10BigNumTable[s_Pow10BigNumTableIndices[num]])
425 {
426 Multiply(ref reference, ref *(BigInteger*)ptr, out reference2);
427 }
428 ref BigInteger reference3 = ref reference2;
429 reference2 = ref reference;
430 reference = ref reference3;
431 }
432 num++;
433 exponent >>= 1;
434 }
435 SetValue(out result, ref reference);
436 }
437
438 private unsafe static uint AddDivisor(ref BigInteger lhs, int lhsStartIndex, ref BigInteger rhs)
439 {
440 int length = lhs._length;
441 int length2 = rhs._length;
442 ulong num = 0uL;
443 for (int i = 0; i < length2; i++)
444 {
445 ref uint reference = ref lhs._blocks[lhsStartIndex + i];
446 ulong num2 = reference + num + rhs._blocks[i];
447 reference = (uint)num2;
448 num = num2 >> 32;
449 }
450 return (uint)num;
451 }
452
453 private static bool DivideGuessTooBig(ulong q, ulong valHi, uint valLo, uint divHi, uint divLo)
454 {
455 ulong num = divHi * q;
456 ulong num2 = divLo * q;
457 num += num2 >> 32;
458 num2 &= 0xFFFFFFFFu;
459 if (num < valHi)
460 {
461 return false;
462 }
463 if (num > valHi)
464 {
465 return true;
466 }
467 if (num2 < valLo)
468 {
469 return false;
470 }
471 if (num2 > valLo)
472 {
473 return true;
474 }
475 return false;
476 }
477
478 private unsafe static uint SubtractDivisor(ref BigInteger lhs, int lhsStartIndex, ref BigInteger rhs, ulong q)
479 {
480 int num = lhs._length - lhsStartIndex;
481 int length = rhs._length;
482 ulong num2 = 0uL;
483 for (int i = 0; i < length; i++)
484 {
485 num2 += rhs._blocks[i] * q;
486 uint num3 = (uint)num2;
487 num2 >>= 32;
488 ref uint reference = ref lhs._blocks[lhsStartIndex + i];
489 if (reference < num3)
490 {
491 num2++;
492 }
493 reference -= num3;
494 }
495 return (uint)num2;
496 }
497
498 public unsafe void Add(uint value)
499 {
500 int length = _length;
501 if (length == 0)
502 {
503 SetUInt32(out this, value);
504 return;
505 }
506 _blocks[0] += value;
507 if (_blocks[0] >= value)
508 {
509 return;
510 }
511 for (int i = 1; i < length; i++)
512 {
513 ref uint reference = ref _blocks[i];
514 reference++;
515 if (_blocks[i] != 0)
516 {
517 return;
518 }
519 }
520 _blocks[length] = 1u;
521 _length = length + 1;
522 }
523
524 public unsafe uint GetBlock(uint index)
525 {
526 return _blocks[index];
527 }
528
529 public int GetLength()
530 {
531 return _length;
532 }
533
534 public bool IsZero()
535 {
536 return _length == 0;
537 }
538
539 public void Multiply(uint value)
540 {
541 Multiply(ref this, value, out this);
542 }
543
544 public void Multiply(ref BigInteger value)
545 {
546 if (value._length <= 1)
547 {
548 Multiply(ref this, value.ToUInt32(), out this);
549 return;
550 }
551 SetValue(out var result, ref this);
552 Multiply(ref result, ref value, out this);
553 }
554
555 public unsafe void Multiply10()
556 {
557 if (!IsZero())
558 {
559 int num = 0;
560 int length = _length;
561 ulong num2 = 0uL;
562 do
563 {
564 ulong num3 = _blocks[num];
565 ulong num4 = (num3 << 3) + (num3 << 1) + num2;
566 num2 = num4 >> 32;
567 _blocks[num] = (uint)num4;
568 num++;
569 }
570 while (num < length);
571 if (num2 != 0L)
572 {
573 _blocks[num] = (uint)num2;
574 _length++;
575 }
576 }
577 }
578
579 public void MultiplyPow10(uint exponent)
580 {
581 if (exponent <= 9)
582 {
583 Multiply(s_Pow10UInt32Table[exponent]);
584 }
585 else if (!IsZero())
586 {
587 Pow10(exponent, out var result);
588 Multiply(ref result);
589 }
590 }
591
592 public unsafe static void SetUInt32(out BigInteger result, uint value)
593 {
594 if (value == 0)
595 {
596 SetZero(out result);
597 return;
598 }
599 result._blocks[0] = value;
600 result._length = 1;
601 }
602
603 public unsafe static void SetUInt64(out BigInteger result, ulong value)
604 {
605 if (value <= uint.MaxValue)
606 {
607 SetUInt32(out result, (uint)value);
608 return;
609 }
610 result._blocks[0] = (uint)value;
611 result._blocks[1] = (uint)(value >> 32);
612 result._length = 2;
613 }
614
615 public unsafe static void SetValue(out BigInteger result, ref BigInteger value)
616 {
617 Buffer.Memmove(elementCount: (nuint)(result._length = value._length), destination: ref result._blocks[0], source: ref value._blocks[0]);
618 }
619
620 public static void SetZero(out BigInteger result)
621 {
622 result._length = 0;
623 }
624
625 public unsafe void ShiftLeft(uint shift)
626 {
627 int length = _length;
628 if (length == 0 || shift == 0)
629 {
630 return;
631 }
632 uint remainder;
633 uint num = DivRem32(shift, out remainder);
634 int num2 = length - 1;
635 int num3 = num2 + (int)num;
636 if (remainder == 0)
637 {
638 while (num2 >= 0)
639 {
640 _blocks[num3] = _blocks[num2];
641 num2--;
642 num3--;
643 }
644 _length += (int)num;
645 Clear(num);
646 return;
647 }
648 num3++;
649 _length = num3 + 1;
650 uint num4 = 32 - remainder;
651 uint num5 = 0u;
652 uint num6 = _blocks[num2];
653 uint num7 = num6 >> (int)num4;
654 while (num2 > 0)
655 {
656 _blocks[num3] = num5 | num7;
657 num5 = num6 << (int)remainder;
658 num2--;
659 num3--;
660 num6 = _blocks[num2];
661 num7 = num6 >> (int)num4;
662 }
663 _blocks[num3] = num5 | num7;
664 _blocks[num3 - 1] = num6 << (int)remainder;
665 Clear(num);
666 if (_blocks[_length - 1] == 0)
667 {
668 _length--;
669 }
670 }
671
672 public unsafe uint ToUInt32()
673 {
674 if (_length > 0)
675 {
676 return _blocks[0];
677 }
678 return 0u;
679 }
680
681 public unsafe ulong ToUInt64()
682 {
683 if (_length > 1)
684 {
685 return ((ulong)_blocks[1] << 32) + _blocks[0];
686 }
687 if (_length > 0)
688 {
689 return _blocks[0];
690 }
691 return 0uL;
692 }
693
694 private unsafe void Clear(uint length)
695 {
696 Buffer.ZeroMemory((byte*)Unsafe.AsPointer(ref _blocks[0]), length * 4);
697 }
698
699 private static uint DivRem32(uint value, out uint remainder)
700 {
701 remainder = value & 0x1Fu;
702 return value >> 5;
703 }
704 }
705
706 internal readonly ref struct DiyFp
707 {
708 public readonly ulong f;
709
710 public readonly int e;
711
712 public static DiyFp CreateAndGetBoundaries(double value, out DiyFp mMinus, out DiyFp mPlus)
713 {
714 DiyFp result = new DiyFp(value);
715 result.GetBoundaries(52, out mMinus, out mPlus);
716 return result;
717 }
718
719 public static DiyFp CreateAndGetBoundaries(float value, out DiyFp mMinus, out DiyFp mPlus)
720 {
721 DiyFp result = new DiyFp(value);
722 result.GetBoundaries(23, out mMinus, out mPlus);
723 return result;
724 }
725
726 public static DiyFp CreateAndGetBoundaries(Half value, out DiyFp mMinus, out DiyFp mPlus)
727 {
728 DiyFp result = new DiyFp(value);
729 result.GetBoundaries(10, out mMinus, out mPlus);
730 return result;
731 }
732
733 public DiyFp(double value)
734 {
736 }
737
738 public DiyFp(float value)
739 {
741 }
742
744 {
746 }
747
748 public DiyFp(ulong f, int e)
749 {
750 this.f = f;
751 this.e = e;
752 }
753
755 {
756 uint num = (uint)(f >> 32);
757 uint num2 = (uint)f;
758 uint num3 = (uint)(other.f >> 32);
759 uint num4 = (uint)other.f;
760 ulong num5 = (ulong)num * (ulong)num3;
761 ulong num6 = (ulong)num2 * (ulong)num3;
762 ulong num7 = (ulong)num * (ulong)num4;
763 ulong num8 = (ulong)num2 * (ulong)num4;
764 ulong num9 = (num8 >> 32) + (uint)num7 + (uint)num6;
765 num9 += 2147483648u;
766 return new DiyFp(num5 + (num7 >> 32) + (num6 >> 32) + (num9 >> 32), e + other.e + 64);
767 }
768
770 {
772 return new DiyFp(f << num, e - num);
773 }
774
776 {
777 return new DiyFp(f - other.f, e);
778 }
779
780 private void GetBoundaries(int implicitBitIndex, out DiyFp mMinus, out DiyFp mPlus)
781 {
782 mPlus = new DiyFp((f << 1) + 1, e - 1).Normalize();
783 if (f == (ulong)(1L << implicitBitIndex))
784 {
785 mMinus = new DiyFp((f << 2) - 1, e - 2);
786 }
787 else
788 {
789 mMinus = new DiyFp((f << 1) - 1, e - 1);
790 }
791 mMinus = new DiyFp(mMinus.f << mMinus.e - mPlus.e, mPlus.e);
792 }
793 }
794
795 internal static class Grisu3
796 {
797 private static readonly short[] s_CachedPowersBinaryExponent = new short[87]
798 {
799 -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
800 -954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
801 -688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
802 -422, -396, -369, -343, -316, -289, -263, -236, -210, -183,
803 -157, -130, -103, -77, -50, -24, 3, 30, 56, 83,
804 109, 136, 162, 189, 216, 242, 269, 295, 322, 348,
805 375, 402, 428, 455, 481, 508, 534, 561, 588, 614,
806 641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
807 907, 933, 960, 986, 1013, 1039, 1066
808 };
809
810 private static readonly short[] s_CachedPowersDecimalExponent = new short[87]
811 {
812 -348, -340, -332, -324, -316, -308, -300, -292, -284, -276,
813 -268, -260, -252, -244, -236, -228, -220, -212, -204, -196,
814 -188, -180, -172, -164, -156, -148, -140, -132, -124, -116,
815 -108, -100, -92, -84, -76, -68, -60, -52, -44, -36,
816 -28, -20, -12, -4, 4, 12, 20, 28, 36, 44,
817 52, 60, 68, 76, 84, 92, 100, 108, 116, 124,
818 132, 140, 148, 156, 164, 172, 180, 188, 196, 204,
819 212, 220, 228, 236, 244, 252, 260, 268, 276, 284,
820 292, 300, 308, 316, 324, 332, 340
821 };
822
823 private static readonly ulong[] s_CachedPowersSignificand = new ulong[87]
824 {
825 18054884314459144840uL, 13451937075301367670uL, 10022474136428063862uL, 14934650266808366570uL, 11127181549972568877uL, 16580792590934885855uL, 12353653155963782858uL, 18408377700990114895uL, 13715310171984221708uL, 10218702384817765436uL,
826 15227053142812498563uL, 11345038669416679861uL, 16905424996341287883uL, 12595523146049147757uL, 9384396036005875287uL, 13983839803942852151uL, 10418772551374772303uL, 15525180923007089351uL, 11567161174868858868uL, 17236413322193710309uL,
827 12842128665889583758uL, 9568131466127621947uL, 14257626930069360058uL, 10622759856335341974uL, 15829145694278690180uL, 11793632577567316726uL, 17573882009934360870uL, 13093562431584567480uL, 9755464219737475723uL, 14536774485912137811uL,
828 10830740992659433045uL, 16139061738043178685uL, 12024538023802026127uL, 17917957937422433684uL, 13349918974505688015uL, 9946464728195732843uL, 14821387422376473014uL, 11042794154864902060uL, 16455045573212060422uL, 12259964326927110867uL,
829 18268770466636286478uL, 13611294676837538539uL, 10141204801825835212uL, 15111572745182864684uL, 11258999068426240000uL, 16777216000000000000uL, 12500000000000000000uL, 9313225746154785156uL, 13877787807814456755uL, 10339757656912845936uL,
830 15407439555097886824uL, 11479437019748901445uL, 17105694144590052135uL, 12744735289059618216uL, 9495567745759798747uL, 14149498560666738074uL, 10542197943230523224uL, 15709099088952724970uL, 11704190886730495818uL, 17440603504673385349uL,
831 12994262207056124023uL, 9681479787123295682uL, 14426529090290212157uL, 10748601772107342003uL, 16016664761464807395uL, 11933345169920330789uL, 17782069995880619868uL, 13248674568444952270uL, 9871031767461413346uL, 14708983551653345445uL,
832 10959046745042015199uL, 16330252207878254650uL, 12166986024289022870uL, 18130221999122236476uL, 13508068024458167312uL, 10064294952495520794uL, 14996968138956309548uL, 11173611982879273257uL, 16649979327439178909uL, 12405201291620119593uL,
833 9242595204427927429uL, 13772540099066387757uL, 10261342003245940623uL, 15290591125556738113uL, 11392378155556871081uL, 16975966327722178521uL, 12648080533535911531uL
834 };
835
836 private static readonly uint[] s_SmallPowersOfTen = new uint[10] { 1u, 10u, 100u, 1000u, 10000u, 100000u, 1000000u, 10000000u, 100000000u, 1000000000u };
837
838 public static bool TryRunDouble(double value, int requestedDigits, ref NumberBuffer number)
839 {
840 double value2 = (double.IsNegative(value) ? (0.0 - value) : value);
841 DiyFp diyFp;
842 bool flag;
843 int length;
844 int decimalExponent;
845 if (requestedDigits == -1)
846 {
847 diyFp = DiyFp.CreateAndGetBoundaries(value2, out var mMinus, out var mPlus);
848 DiyFp w = diyFp.Normalize();
849 flag = TryRunShortest(in mMinus, in w, in mPlus, number.Digits, out length, out decimalExponent);
850 }
851 else
852 {
853 diyFp = new DiyFp(value2);
854 DiyFp w2 = diyFp.Normalize();
855 flag = TryRunCounted(in w2, requestedDigits, number.Digits, out length, out decimalExponent);
856 }
857 if (flag)
858 {
859 number.Scale = length + decimalExponent;
860 number.Digits[length] = 0;
861 number.DigitsCount = length;
862 }
863 return flag;
864 }
865
866 public static bool TryRunHalf(Half value, int requestedDigits, ref NumberBuffer number)
867 {
868 Half value2 = (Half.IsNegative(value) ? Half.Negate(value) : value);
869 DiyFp diyFp;
870 bool flag;
871 int length;
872 int decimalExponent;
873 if (requestedDigits == -1)
874 {
875 diyFp = DiyFp.CreateAndGetBoundaries(value2, out var mMinus, out var mPlus);
876 DiyFp w = diyFp.Normalize();
877 flag = TryRunShortest(in mMinus, in w, in mPlus, number.Digits, out length, out decimalExponent);
878 }
879 else
880 {
881 diyFp = new DiyFp(value2);
882 DiyFp w2 = diyFp.Normalize();
883 flag = TryRunCounted(in w2, requestedDigits, number.Digits, out length, out decimalExponent);
884 }
885 if (flag)
886 {
887 number.Scale = length + decimalExponent;
888 number.Digits[length] = 0;
889 number.DigitsCount = length;
890 }
891 return flag;
892 }
893
894 public static bool TryRunSingle(float value, int requestedDigits, ref NumberBuffer number)
895 {
896 float value2 = (float.IsNegative(value) ? (0f - value) : value);
897 DiyFp diyFp;
898 bool flag;
899 int length;
900 int decimalExponent;
901 if (requestedDigits == -1)
902 {
903 diyFp = DiyFp.CreateAndGetBoundaries(value2, out var mMinus, out var mPlus);
904 DiyFp w = diyFp.Normalize();
905 flag = TryRunShortest(in mMinus, in w, in mPlus, number.Digits, out length, out decimalExponent);
906 }
907 else
908 {
909 diyFp = new DiyFp(value2);
910 DiyFp w2 = diyFp.Normalize();
911 flag = TryRunCounted(in w2, requestedDigits, number.Digits, out length, out decimalExponent);
912 }
913 if (flag)
914 {
915 number.Scale = length + decimalExponent;
916 number.Digits[length] = 0;
917 number.DigitsCount = length;
918 }
919 return flag;
920 }
921
922 private static bool TryRunCounted(in DiyFp w, int requestedDigits, Span<byte> buffer, out int length, out int decimalExponent)
923 {
924 int minExponent = -60 - (w.e + 64);
925 int maxExponent = -32 - (w.e + 64);
926 int decimalExponent2;
927 DiyFp other = GetCachedPowerForBinaryExponentRange(minExponent, maxExponent, out decimalExponent2);
928 DiyFp w2 = w.Multiply(in other);
929 int kappa;
930 bool result = TryDigitGenCounted(in w2, requestedDigits, buffer, out length, out kappa);
931 decimalExponent = -decimalExponent2 + kappa;
932 return result;
933 }
934
935 private static bool TryRunShortest(in DiyFp boundaryMinus, in DiyFp w, in DiyFp boundaryPlus, Span<byte> buffer, out int length, out int decimalExponent)
936 {
937 int minExponent = -60 - (w.e + 64);
938 int maxExponent = -32 - (w.e + 64);
939 int decimalExponent2;
940 DiyFp other = GetCachedPowerForBinaryExponentRange(minExponent, maxExponent, out decimalExponent2);
941 DiyFp w2 = w.Multiply(in other);
942 DiyFp low = boundaryMinus.Multiply(in other);
943 DiyFp high = boundaryPlus.Multiply(in other);
944 int kappa;
945 bool result = TryDigitGenShortest(in low, in w2, in high, buffer, out length, out kappa);
946 decimalExponent = -decimalExponent2 + kappa;
947 return result;
948 }
949
950 private static uint BiggestPowerTen(uint number, int numberBits, out int exponentPlusOne)
951 {
952 int num = (numberBits + 1) * 1233 >> 12;
953 uint num2 = s_SmallPowersOfTen[num];
954 if (number < num2)
955 {
956 num--;
957 num2 = s_SmallPowersOfTen[num];
958 }
959 exponentPlusOne = num + 1;
960 return num2;
961 }
962
963 private static bool TryDigitGenCounted(in DiyFp w, int requestedDigits, Span<byte> buffer, out int length, out int kappa)
964 {
965 ulong num = 1uL;
966 DiyFp diyFp = new DiyFp((ulong)(1L << -w.e), w.e);
967 uint num2 = (uint)(w.f >> -diyFp.e);
968 ulong num3 = w.f & (diyFp.f - 1);
969 if (num3 == 0L && (requestedDigits >= 11 || num2 < s_SmallPowersOfTen[requestedDigits - 1]))
970 {
971 length = 0;
972 kappa = 0;
973 return false;
974 }
975 uint num4 = BiggestPowerTen(num2, 64 - -diyFp.e, out kappa);
976 length = 0;
977 while (kappa > 0)
978 {
979 uint num5;
980 (num5, num2) = Math.DivRem(num2, num4);
981 buffer[length] = (byte)(48 + num5);
982 length++;
983 requestedDigits--;
984 kappa--;
985 if (requestedDigits == 0)
986 {
987 break;
988 }
989 num4 /= 10;
990 }
991 if (requestedDigits == 0)
992 {
993 ulong rest = ((ulong)num2 << -diyFp.e) + num3;
994 return TryRoundWeedCounted(buffer, length, rest, (ulong)num4 << -diyFp.e, num, ref kappa);
995 }
996 while (requestedDigits > 0 && num3 > num)
997 {
998 num3 *= 10;
999 num *= 10;
1000 uint num6 = (uint)(num3 >> -diyFp.e);
1001 buffer[length] = (byte)(48 + num6);
1002 length++;
1003 requestedDigits--;
1004 kappa--;
1005 num3 &= diyFp.f - 1;
1006 }
1007 if (requestedDigits != 0)
1008 {
1009 buffer[0] = 0;
1010 length = 0;
1011 kappa = 0;
1012 return false;
1013 }
1014 return TryRoundWeedCounted(buffer, length, num3, diyFp.f, num, ref kappa);
1015 }
1016
1017 private static bool TryDigitGenShortest(in DiyFp low, in DiyFp w, in DiyFp high, Span<byte> buffer, out int length, out int kappa)
1018 {
1019 ulong num = 1uL;
1020 DiyFp other = new DiyFp(low.f - num, low.e);
1021 DiyFp diyFp = new DiyFp(high.f + num, high.e);
1022 DiyFp diyFp2 = diyFp.Subtract(in other);
1023 DiyFp diyFp3 = new DiyFp((ulong)(1L << -w.e), w.e);
1024 uint num2 = (uint)(diyFp.f >> -diyFp3.e);
1025 ulong num3 = diyFp.f & (diyFp3.f - 1);
1026 uint num4 = BiggestPowerTen(num2, 64 - -diyFp3.e, out kappa);
1027 length = 0;
1028 while (kappa > 0)
1029 {
1030 uint num5;
1031 (num5, num2) = Math.DivRem(num2, num4);
1032 buffer[length] = (byte)(48 + num5);
1033 length++;
1034 kappa--;
1035 ulong num6 = ((ulong)num2 << -diyFp3.e) + num3;
1036 if (num6 < diyFp2.f)
1037 {
1038 return TryRoundWeedShortest(buffer, length, diyFp.Subtract(in w).f, diyFp2.f, num6, (ulong)num4 << -diyFp3.e, num);
1039 }
1040 num4 /= 10;
1041 }
1042 do
1043 {
1044 num3 *= 10;
1045 num *= 10;
1046 diyFp2 = new DiyFp(diyFp2.f * 10, diyFp2.e);
1047 uint num7 = (uint)(num3 >> -diyFp3.e);
1048 buffer[length] = (byte)(48 + num7);
1049 length++;
1050 kappa--;
1051 num3 &= diyFp3.f - 1;
1052 }
1053 while (num3 >= diyFp2.f);
1054 return TryRoundWeedShortest(buffer, length, diyFp.Subtract(in w).f * num, diyFp2.f, num3, diyFp3.f, num);
1055 }
1056
1057 private static DiyFp GetCachedPowerForBinaryExponentRange(int minExponent, int maxExponent, out int decimalExponent)
1058 {
1059 double num = Math.Ceiling((double)(minExponent + 64 - 1) * 0.3010299956639812);
1060 int num2 = (348 + (int)num - 1) / 8 + 1;
1061 decimalExponent = s_CachedPowersDecimalExponent[num2];
1063 }
1064
1065 private static bool TryRoundWeedCounted(Span<byte> buffer, int length, ulong rest, ulong tenKappa, ulong unit, ref int kappa)
1066 {
1067 if (unit >= tenKappa || tenKappa - unit <= unit)
1068 {
1069 return false;
1070 }
1071 if (tenKappa - rest > rest && tenKappa - 2 * rest >= 2 * unit)
1072 {
1073 return true;
1074 }
1075 if (rest > unit && (tenKappa <= rest - unit || tenKappa - (rest - unit) <= rest - unit))
1076 {
1077 buffer[length - 1]++;
1078 int num = length - 1;
1079 while (num > 0 && buffer[num] == 58)
1080 {
1081 buffer[num] = 48;
1082 buffer[num - 1]++;
1083 num--;
1084 }
1085 if (buffer[0] == 58)
1086 {
1087 buffer[0] = 49;
1088 kappa++;
1089 }
1090 return true;
1091 }
1092 return false;
1093 }
1094
1095 private static bool TryRoundWeedShortest(Span<byte> buffer, int length, ulong distanceTooHighW, ulong unsafeInterval, ulong rest, ulong tenKappa, ulong unit)
1096 {
1097 ulong num = distanceTooHighW - unit;
1098 ulong num2 = distanceTooHighW + unit;
1099 while (rest < num && unsafeInterval - rest >= tenKappa && (rest + tenKappa < num || num - rest >= rest + tenKappa - num))
1100 {
1101 buffer[length - 1]--;
1102 rest += tenKappa;
1103 }
1104 if (rest < num2 && unsafeInterval - rest >= tenKappa && (rest + tenKappa < num2 || num2 - rest > rest + tenKappa - num2))
1105 {
1106 return false;
1107 }
1108 if (2 * unit <= rest)
1109 {
1110 return rest <= unsafeInterval - 4 * unit;
1111 }
1112 return false;
1113 }
1114 }
1115
1116 internal ref struct NumberBuffer
1117 {
1118 public int DigitsCount;
1119
1120 public int Scale;
1121
1122 public bool IsNegative;
1123
1124 public bool HasNonZeroTail;
1125
1127
1129
1130 public unsafe NumberBuffer(NumberBufferKind kind, byte* digits, int digitsLength)
1131 {
1132 DigitsCount = 0;
1133 Scale = 0;
1134 IsNegative = false;
1135 HasNonZeroTail = false;
1136 Kind = kind;
1137 Digits = new Span<byte>(digits, digitsLength);
1138 Digits[0] = 0;
1139 }
1140
1141 public unsafe byte* GetDigitsPointer()
1142 {
1143 return (byte*)Unsafe.AsPointer(ref Digits[0]);
1144 }
1145
1146 public override string ToString()
1147 {
1148 StringBuilder stringBuilder = new StringBuilder();
1149 stringBuilder.Append('[');
1150 stringBuilder.Append('"');
1151 for (int i = 0; i < Digits.Length; i++)
1152 {
1153 byte b = Digits[i];
1154 if (b == 0)
1155 {
1156 break;
1157 }
1158 stringBuilder.Append((char)b);
1159 }
1160 stringBuilder.Append('"');
1161 stringBuilder.Append(", Length = ").Append(DigitsCount);
1162 stringBuilder.Append(", Scale = ").Append(Scale);
1163 stringBuilder.Append(", IsNegative = ").Append(IsNegative);
1164 stringBuilder.Append(", HasNonZeroTail = ").Append(HasNonZeroTail);
1165 stringBuilder.Append(", Kind = ").Append(Kind);
1166 stringBuilder.Append(']');
1167 return stringBuilder.ToString();
1168 }
1169 }
1170
1171 internal enum NumberBufferKind : byte
1172 {
1173 Unknown,
1174 Integer,
1175 Decimal,
1177 }
1178
1179 public readonly struct FloatingPointInfo
1180 {
1181 public static readonly FloatingPointInfo Double = new FloatingPointInfo(52, 11, 1023, 1023, 9218868437227405312uL);
1182
1183 public static readonly FloatingPointInfo Single = new FloatingPointInfo(23, 8, 127, 127, 2139095040uL);
1184
1185 public static readonly FloatingPointInfo Half = new FloatingPointInfo(10, 5, 15, 15, 31744uL);
1186
1187 [CompilerGenerated]
1189
1190 public ulong ZeroBits { get; }
1191
1192 public ulong InfinityBits { get; }
1193
1194 public ulong NormalMantissaMask { get; }
1195
1196 public ulong DenormalMantissaMask { get; }
1197
1198 public int MinBinaryExponent { get; }
1199
1200 public int MaxBinaryExponent { get; }
1201
1202 public int ExponentBias { get; }
1203
1204 public int OverflowDecimalExponent { get; }
1205
1206 public ushort NormalMantissaBits { get; }
1207
1208 public ushort DenormalMantissaBits { get; }
1209
1210 public FloatingPointInfo(ushort denormalMantissaBits, ushort exponentBits, int maxBinaryExponent, int exponentBias, ulong infinityBits)
1211 {
1213 DenormalMantissaBits = denormalMantissaBits;
1214 NormalMantissaBits = (ushort)(denormalMantissaBits + 1);
1215 OverflowDecimalExponent = (maxBinaryExponent + 2 * NormalMantissaBits) / 3;
1216 ExponentBias = exponentBias;
1217 MaxBinaryExponent = maxBinaryExponent;
1218 MinBinaryExponent = 1 - maxBinaryExponent;
1219 DenormalMantissaMask = (ulong)((1L << (int)denormalMantissaBits) - 1);
1220 NormalMantissaMask = (ulong)((1L << (int)NormalMantissaBits) - 1);
1221 InfinityBits = infinityBits;
1222 ZeroBits = 0uL;
1223 }
1224 }
1225
1226 internal enum ParsingStatus
1227 {
1228 OK,
1229 Failed,
1230 Overflow
1231 }
1232
1233 private static readonly string[] s_singleDigitStringCache = new string[10] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
1234
1235 private static readonly string[] s_posCurrencyFormats = new string[4] { "$#", "#$", "$ #", "# $" };
1236
1237 private static readonly string[] s_negCurrencyFormats = new string[17]
1238 {
1239 "($#)", "-$#", "$-#", "$#-", "(#$)", "-#$", "#-$", "#$-", "-# $", "-$ #",
1240 "# $-", "$ #-", "$ -#", "#- $", "($ #)", "(# $)", "$- #"
1241 };
1242
1243 private static readonly string[] s_posPercentFormats = new string[4] { "# %", "#%", "%#", "% #" };
1244
1245 private static readonly string[] s_negPercentFormats = new string[12]
1246 {
1247 "-# %", "-#%", "-%#", "%-#", "%#-", "#-%", "#%-", "-% #", "# %-", "% #-",
1248 "% -#", "#- %"
1249 };
1250
1251 private static readonly string[] s_negNumberFormats = new string[5] { "(#)", "-#", "- #", "#-", "# -" };
1252
1253 private static readonly float[] s_Pow10SingleTable = new float[11]
1254 {
1255 1f, 10f, 100f, 1000f, 10000f, 100000f, 1000000f, 10000000f, 100000000f, 1E+09f,
1256 1E+10f
1257 };
1258
1259 private static readonly double[] s_Pow10DoubleTable = new double[23]
1260 {
1261 1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0,
1262 10000000000.0, 100000000000.0, 1000000000000.0, 10000000000000.0, 100000000000000.0, 1000000000000000.0, 10000000000000000.0, 1E+17, 1E+18, 1E+19,
1263 1E+20, 1E+21, 1E+22
1264 };
1265
1266 public static void Dragon4Double(double value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number)
1267 {
1268 double num = (double.IsNegative(value) ? (0.0 - value) : value);
1269 int exponent;
1270 ulong num2 = ExtractFractionAndBiasedExponent(value, out exponent);
1271 bool hasUnequalMargins = false;
1272 uint mantissaHighBitIdx;
1273 if (num2 >> 52 != 0L)
1274 {
1275 mantissaHighBitIdx = 52u;
1276 hasUnequalMargins = num2 == 4503599627370496L;
1277 }
1278 else
1279 {
1280 mantissaHighBitIdx = (uint)BitOperations.Log2(num2);
1281 }
1282 int decimalExponent;
1283 int num3 = (int)Dragon4(num2, exponent, mantissaHighBitIdx, hasUnequalMargins, cutoffNumber, isSignificantDigits, number.Digits, out decimalExponent);
1284 number.Scale = decimalExponent + 1;
1285 number.Digits[num3] = 0;
1286 number.DigitsCount = num3;
1287 }
1288
1289 public static void Dragon4Half(Half value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number)
1290 {
1291 Half half = (Half.IsNegative(value) ? Half.Negate(value) : value);
1292 int exponent;
1293 ushort num = ExtractFractionAndBiasedExponent(value, out exponent);
1294 bool hasUnequalMargins = false;
1295 uint mantissaHighBitIdx;
1296 if (num >> 10 != 0)
1297 {
1298 mantissaHighBitIdx = 10u;
1299 hasUnequalMargins = num == 1024;
1300 }
1301 else
1302 {
1303 mantissaHighBitIdx = (uint)BitOperations.Log2(num);
1304 }
1305 int decimalExponent;
1306 int num2 = (int)Dragon4(num, exponent, mantissaHighBitIdx, hasUnequalMargins, cutoffNumber, isSignificantDigits, number.Digits, out decimalExponent);
1307 number.Scale = decimalExponent + 1;
1308 number.Digits[num2] = 0;
1309 number.DigitsCount = num2;
1310 }
1311
1312 public static void Dragon4Single(float value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number)
1313 {
1314 float num = (float.IsNegative(value) ? (0f - value) : value);
1315 int exponent;
1316 uint num2 = ExtractFractionAndBiasedExponent(value, out exponent);
1317 bool hasUnequalMargins = false;
1318 uint mantissaHighBitIdx;
1319 if (num2 >> 23 != 0)
1320 {
1321 mantissaHighBitIdx = 23u;
1322 hasUnequalMargins = num2 == 8388608;
1323 }
1324 else
1325 {
1326 mantissaHighBitIdx = (uint)BitOperations.Log2(num2);
1327 }
1328 int decimalExponent;
1329 int num3 = (int)Dragon4(num2, exponent, mantissaHighBitIdx, hasUnequalMargins, cutoffNumber, isSignificantDigits, number.Digits, out decimalExponent);
1330 number.Scale = decimalExponent + 1;
1331 number.Digits[num3] = 0;
1332 number.DigitsCount = num3;
1333 }
1334
1335 private unsafe static uint Dragon4(ulong mantissa, int exponent, uint mantissaHighBitIdx, bool hasUnequalMargins, int cutoffNumber, bool isSignificantDigits, Span<byte> buffer, out int decimalExponent)
1336 {
1337 int num = 0;
1338 BigInteger lhs;
1339 BigInteger rhs;
1340 BigInteger result;
1341 BigInteger* ptr;
1342 if (hasUnequalMargins)
1343 {
1344 BigInteger result2;
1345 if (exponent > 0)
1346 {
1347 BigInteger.SetUInt64(out lhs, 4 * mantissa);
1348 lhs.ShiftLeft((uint)exponent);
1349 BigInteger.SetUInt32(out rhs, 4u);
1350 BigInteger.Pow2((uint)exponent, out result);
1351 BigInteger.Pow2((uint)(exponent + 1), out result2);
1352 }
1353 else
1354 {
1355 BigInteger.SetUInt64(out lhs, 4 * mantissa);
1356 BigInteger.Pow2((uint)(-exponent + 2), out rhs);
1357 BigInteger.SetUInt32(out result, 1u);
1358 BigInteger.SetUInt32(out result2, 2u);
1359 }
1360 ptr = &result2;
1361 }
1362 else
1363 {
1364 if (exponent > 0)
1365 {
1366 BigInteger.SetUInt64(out lhs, 2 * mantissa);
1367 lhs.ShiftLeft((uint)exponent);
1368 BigInteger.SetUInt32(out rhs, 2u);
1369 BigInteger.Pow2((uint)exponent, out result);
1370 }
1371 else
1372 {
1373 BigInteger.SetUInt64(out lhs, 2 * mantissa);
1374 BigInteger.Pow2((uint)(-exponent + 1), out rhs);
1375 BigInteger.SetUInt32(out result, 1u);
1376 }
1377 ptr = &result;
1378 }
1379 int num2 = (int)Math.Ceiling((double)((int)mantissaHighBitIdx + exponent) * 0.3010299956639812 - 0.69);
1380 if (num2 > 0)
1381 {
1382 rhs.MultiplyPow10((uint)num2);
1383 }
1384 else if (num2 < 0)
1385 {
1386 BigInteger.Pow10((uint)(-num2), out var result3);
1387 lhs.Multiply(ref result3);
1388 result.Multiply(ref result3);
1389 if (ptr != &result)
1390 {
1391 BigInteger.Multiply(ref result, 2u, out *ptr);
1392 }
1393 }
1394 bool flag = mantissa % 2 == 0;
1395 bool flag2 = false;
1396 if (cutoffNumber == -1)
1397 {
1398 BigInteger.Add(ref lhs, ref *ptr, out var result4);
1399 int num3 = BigInteger.Compare(ref result4, ref rhs);
1400 flag2 = (flag ? (num3 >= 0) : (num3 > 0));
1401 }
1402 else
1403 {
1404 flag2 = BigInteger.Compare(ref lhs, ref rhs) >= 0;
1405 }
1406 if (flag2)
1407 {
1408 num2++;
1409 }
1410 else
1411 {
1412 lhs.Multiply10();
1413 result.Multiply10();
1414 if (ptr != &result)
1415 {
1416 BigInteger.Multiply(ref result, 2u, out *ptr);
1417 }
1418 }
1419 int num4 = num2 - buffer.Length;
1420 if (cutoffNumber != -1)
1421 {
1422 int num5 = 0;
1423 num5 = ((!isSignificantDigits) ? (-cutoffNumber) : (num2 - cutoffNumber));
1424 if (num5 > num4)
1425 {
1426 num4 = num5;
1427 }
1428 }
1429 num2 = (decimalExponent = num2 - 1);
1430 uint block = rhs.GetBlock((uint)(rhs.GetLength() - 1));
1431 if (block < 8 || block > 429496729)
1432 {
1433 uint num6 = (uint)BitOperations.Log2(block);
1434 uint shift = (59 - num6) % 32;
1435 rhs.ShiftLeft(shift);
1436 lhs.ShiftLeft(shift);
1437 result.ShiftLeft(shift);
1438 if (ptr != &result)
1439 {
1440 BigInteger.Multiply(ref result, 2u, out *ptr);
1441 }
1442 }
1443 bool flag3;
1444 bool flag4;
1445 uint num7;
1446 if (cutoffNumber == -1)
1447 {
1448 while (true)
1449 {
1450 num7 = BigInteger.HeuristicDivide(ref lhs, ref rhs);
1451 BigInteger.Add(ref lhs, ref *ptr, out var result5);
1452 int num8 = BigInteger.Compare(ref lhs, ref result);
1453 int num9 = BigInteger.Compare(ref result5, ref rhs);
1454 if (flag)
1455 {
1456 flag3 = num8 <= 0;
1457 flag4 = num9 >= 0;
1458 }
1459 else
1460 {
1461 flag3 = num8 < 0;
1462 flag4 = num9 > 0;
1463 }
1464 if (flag3 || flag4 || num2 == num4)
1465 {
1466 break;
1467 }
1468 buffer[num] = (byte)(48 + num7);
1469 num++;
1470 lhs.Multiply10();
1471 result.Multiply10();
1472 if (ptr != &result)
1473 {
1474 BigInteger.Multiply(ref result, 2u, out *ptr);
1475 }
1476 num2--;
1477 }
1478 }
1479 else
1480 {
1481 if (num2 < num4)
1482 {
1483 num7 = BigInteger.HeuristicDivide(ref lhs, ref rhs);
1484 if (num7 > 5 || (num7 == 5 && !lhs.IsZero()))
1485 {
1486 decimalExponent++;
1487 num7 = 1u;
1488 }
1489 buffer[num] = (byte)(48 + num7);
1490 return (uint)(num + 1);
1491 }
1492 flag3 = false;
1493 flag4 = false;
1494 while (true)
1495 {
1496 num7 = BigInteger.HeuristicDivide(ref lhs, ref rhs);
1497 if (lhs.IsZero() || num2 <= num4)
1498 {
1499 break;
1500 }
1501 buffer[num] = (byte)(48 + num7);
1502 num++;
1503 lhs.Multiply10();
1504 num2--;
1505 }
1506 }
1507 bool flag5 = flag3;
1508 if (flag3 == flag4)
1509 {
1510 lhs.ShiftLeft(1u);
1511 int num10 = BigInteger.Compare(ref lhs, ref rhs);
1512 flag5 = num10 < 0;
1513 if (num10 == 0)
1514 {
1515 flag5 = (num7 & 1) == 0;
1516 }
1517 }
1518 if (flag5)
1519 {
1520 buffer[num] = (byte)(48 + num7);
1521 num++;
1522 }
1523 else if (num7 == 9)
1524 {
1525 while (true)
1526 {
1527 if (num == 0)
1528 {
1529 buffer[num] = 49;
1530 num++;
1531 decimalExponent++;
1532 break;
1533 }
1534 num--;
1535 if (buffer[num] != 57)
1536 {
1537 buffer[num]++;
1538 num++;
1539 break;
1540 }
1541 }
1542 }
1543 else
1544 {
1545 buffer[num] = (byte)(48 + num7 + 1);
1546 num++;
1547 }
1548 return (uint)num;
1549 }
1550
1551 public unsafe static string FormatDecimal(decimal value, ReadOnlySpan<char> format, NumberFormatInfo info)
1552 {
1553 int digits;
1554 char c = ParseFormatSpecifier(format, out digits);
1555 byte* digits2 = stackalloc byte[31];
1556 NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, digits2, 31);
1557 DecimalToNumber(ref value, ref number);
1558 char* pointer = stackalloc char[32];
1560 if (c != 0)
1561 {
1562 NumberToString(ref sb, ref number, c, digits, info);
1563 }
1564 else
1565 {
1566 NumberToStringFormat(ref sb, ref number, format, info);
1567 }
1568 return sb.ToString();
1569 }
1570
1571 public unsafe static bool TryFormatDecimal(decimal value, ReadOnlySpan<char> format, NumberFormatInfo info, Span<char> destination, out int charsWritten)
1572 {
1573 int digits;
1574 char c = ParseFormatSpecifier(format, out digits);
1575 byte* digits2 = stackalloc byte[31];
1576 NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, digits2, 31);
1577 DecimalToNumber(ref value, ref number);
1578 char* pointer = stackalloc char[32];
1580 if (c != 0)
1581 {
1582 NumberToString(ref sb, ref number, c, digits, info);
1583 }
1584 else
1585 {
1586 NumberToStringFormat(ref sb, ref number, format, info);
1587 }
1588 return sb.TryCopyTo(destination, out charsWritten);
1589 }
1590
1591 internal unsafe static void DecimalToNumber(ref decimal d, ref NumberBuffer number)
1592 {
1593 byte* digitsPointer = number.GetDigitsPointer();
1594 number.DigitsCount = 29;
1595 number.IsNegative = d.IsNegative;
1596 byte* bufferEnd = digitsPointer + 29;
1597 while ((d.Mid | d.High) != 0)
1598 {
1599 bufferEnd = UInt32ToDecChars(bufferEnd, decimal.DecDivMod1E9(ref d), 9);
1600 }
1601 bufferEnd = UInt32ToDecChars(bufferEnd, d.Low, 0);
1602 int num = (number.DigitsCount = (int)(digitsPointer + 29 - bufferEnd));
1603 number.Scale = num - d.Scale;
1604 byte* digitsPointer2 = number.GetDigitsPointer();
1605 while (--num >= 0)
1606 {
1607 *(digitsPointer2++) = *(bufferEnd++);
1608 }
1609 *digitsPointer2 = 0;
1610 }
1611
1612 public static string FormatDouble(double value, string format, NumberFormatInfo info)
1613 {
1614 Span<char> initialBuffer = stackalloc char[32];
1615 ValueStringBuilder sb = new ValueStringBuilder(initialBuffer);
1616 return FormatDouble(ref sb, value, format, info) ?? sb.ToString();
1617 }
1618
1619 public static bool TryFormatDouble(double value, ReadOnlySpan<char> format, NumberFormatInfo info, Span<char> destination, out int charsWritten)
1620 {
1621 Span<char> initialBuffer = stackalloc char[32];
1622 ValueStringBuilder sb = new ValueStringBuilder(initialBuffer);
1623 string text = FormatDouble(ref sb, value, format, info);
1624 if (text == null)
1625 {
1626 return sb.TryCopyTo(destination, out charsWritten);
1627 }
1628 return TryCopyTo(text, destination, out charsWritten);
1629 }
1630
1631 private static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int precision, NumberFormatInfo info, out bool isSignificantDigits)
1632 {
1633 if (fmt == '\0')
1634 {
1635 isSignificantDigits = true;
1636 return precision;
1637 }
1638 int result = precision;
1639 switch (fmt)
1640 {
1641 case 'C':
1642 case 'c':
1643 if (precision == -1)
1644 {
1645 precision = info.CurrencyDecimalDigits;
1646 }
1647 isSignificantDigits = false;
1648 break;
1649 case 'E':
1650 case 'e':
1651 if (precision == -1)
1652 {
1653 precision = 6;
1654 }
1655 precision++;
1656 isSignificantDigits = true;
1657 break;
1658 case 'F':
1659 case 'N':
1660 case 'f':
1661 case 'n':
1662 if (precision == -1)
1663 {
1664 precision = info.NumberDecimalDigits;
1665 }
1666 isSignificantDigits = false;
1667 break;
1668 case 'G':
1669 case 'g':
1670 if (precision == 0)
1671 {
1672 precision = -1;
1673 }
1674 isSignificantDigits = true;
1675 break;
1676 case 'P':
1677 case 'p':
1678 if (precision == -1)
1679 {
1680 precision = info.PercentDecimalDigits;
1681 }
1682 precision += 2;
1683 isSignificantDigits = false;
1684 break;
1685 case 'R':
1686 case 'r':
1687 precision = -1;
1688 isSignificantDigits = true;
1689 break;
1690 default:
1692 }
1693 return result;
1694 }
1695
1697 {
1698 if (!double.IsFinite(value))
1699 {
1700 if (double.IsNaN(value))
1701 {
1702 return info.NaNSymbol;
1703 }
1704 if (!double.IsNegative(value))
1705 {
1706 return info.PositiveInfinitySymbol;
1707 }
1708 return info.NegativeInfinitySymbol;
1709 }
1710 int digits;
1711 char c = ParseFormatSpecifier(format, out digits);
1712 byte* digits2 = stackalloc byte[769];
1713 if (c == '\0')
1714 {
1715 digits = 15;
1716 }
1717 NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, digits2, 769);
1718 number.IsNegative = double.IsNegative(value);
1719 bool isSignificantDigits;
1720 int nMaxDigits = GetFloatingPointMaxDigitsAndPrecision(c, ref digits, info, out isSignificantDigits);
1721 if (value != 0.0 && (!isSignificantDigits || !Grisu3.TryRunDouble(value, digits, ref number)))
1722 {
1723 Dragon4Double(value, digits, isSignificantDigits, ref number);
1724 }
1725 if (c != 0)
1726 {
1727 if (digits == -1)
1728 {
1729 nMaxDigits = Math.Max(number.DigitsCount, 17);
1730 }
1731 NumberToString(ref sb, ref number, c, nMaxDigits, info);
1732 }
1733 else
1734 {
1735 NumberToStringFormat(ref sb, ref number, format, info);
1736 }
1737 return null;
1738 }
1739
1740 public static string FormatSingle(float value, string format, NumberFormatInfo info)
1741 {
1742 Span<char> initialBuffer = stackalloc char[32];
1743 ValueStringBuilder sb = new ValueStringBuilder(initialBuffer);
1744 return FormatSingle(ref sb, value, format, info) ?? sb.ToString();
1745 }
1746
1748 {
1749 Span<char> initialBuffer = stackalloc char[32];
1750 ValueStringBuilder sb = new ValueStringBuilder(initialBuffer);
1751 string text = FormatSingle(ref sb, value, format, info);
1752 if (text == null)
1753 {
1754 return sb.TryCopyTo(destination, out charsWritten);
1755 }
1756 return TryCopyTo(text, destination, out charsWritten);
1757 }
1758
1760 {
1761 if (!float.IsFinite(value))
1762 {
1763 if (float.IsNaN(value))
1764 {
1765 return info.NaNSymbol;
1766 }
1767 if (!float.IsNegative(value))
1768 {
1769 return info.PositiveInfinitySymbol;
1770 }
1771 return info.NegativeInfinitySymbol;
1772 }
1773 int digits;
1774 char c = ParseFormatSpecifier(format, out digits);
1775 byte* digits2 = stackalloc byte[114];
1776 if (c == '\0')
1777 {
1778 digits = 7;
1779 }
1780 NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, digits2, 114);
1781 number.IsNegative = float.IsNegative(value);
1782 bool isSignificantDigits;
1783 int nMaxDigits = GetFloatingPointMaxDigitsAndPrecision(c, ref digits, info, out isSignificantDigits);
1784 if (value != 0f && (!isSignificantDigits || !Grisu3.TryRunSingle(value, digits, ref number)))
1785 {
1786 Dragon4Single(value, digits, isSignificantDigits, ref number);
1787 }
1788 if (c != 0)
1789 {
1790 if (digits == -1)
1791 {
1792 nMaxDigits = Math.Max(number.DigitsCount, 9);
1793 }
1794 NumberToString(ref sb, ref number, c, nMaxDigits, info);
1795 }
1796 else
1797 {
1798 NumberToStringFormat(ref sb, ref number, format, info);
1799 }
1800 return null;
1801 }
1802
1803 public static string FormatHalf(Half value, string format, NumberFormatInfo info)
1804 {
1805 Span<char> initialBuffer = stackalloc char[32];
1806 ValueStringBuilder sb = new ValueStringBuilder(initialBuffer);
1807 return FormatHalf(ref sb, value, format, info) ?? sb.ToString();
1808 }
1809
1811 {
1812 if (!Half.IsFinite(value))
1813 {
1814 if (Half.IsNaN(value))
1815 {
1816 return info.NaNSymbol;
1817 }
1818 if (!Half.IsNegative(value))
1819 {
1820 return info.PositiveInfinitySymbol;
1821 }
1822 return info.NegativeInfinitySymbol;
1823 }
1824 int digits;
1825 char c = ParseFormatSpecifier(format, out digits);
1826 byte* digits2 = stackalloc byte[21];
1827 if (c == '\0')
1828 {
1829 digits = 5;
1830 }
1831 NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, digits2, 21);
1832 number.IsNegative = Half.IsNegative(value);
1833 bool isSignificantDigits;
1834 int nMaxDigits = GetFloatingPointMaxDigitsAndPrecision(c, ref digits, info, out isSignificantDigits);
1835 if (value != default(Half) && (!isSignificantDigits || !Grisu3.TryRunHalf(value, digits, ref number)))
1836 {
1837 Dragon4Half(value, digits, isSignificantDigits, ref number);
1838 }
1839 if (c != 0)
1840 {
1841 if (digits == -1)
1842 {
1843 nMaxDigits = Math.Max(number.DigitsCount, 5);
1844 }
1845 NumberToString(ref sb, ref number, c, nMaxDigits, info);
1846 }
1847 else
1848 {
1849 NumberToStringFormat(ref sb, ref number, format, info);
1850 }
1851 return null;
1852 }
1853
1855 {
1856 Span<char> initialBuffer = stackalloc char[32];
1857 ValueStringBuilder sb = new ValueStringBuilder(initialBuffer);
1858 string text = FormatHalf(ref sb, value, format, info);
1859 if (text == null)
1860 {
1861 return sb.TryCopyTo(destination, out charsWritten);
1862 }
1863 return TryCopyTo(text, destination, out charsWritten);
1864 }
1865
1866 private static bool TryCopyTo(string source, Span<char> destination, out int charsWritten)
1867 {
1868 if (source.TryCopyTo(destination))
1869 {
1870 charsWritten = source.Length;
1871 return true;
1872 }
1873 charsWritten = 0;
1874 return false;
1875 }
1876
1877 private static char GetHexBase(char fmt)
1878 {
1879 return (char)(fmt - 33);
1880 }
1881
1882 public static string FormatInt32(int value, int hexMask, string format, IFormatProvider provider)
1883 {
1884 if (string.IsNullOrEmpty(format))
1885 {
1886 if (value < 0)
1887 {
1888 return NegativeInt32ToDecStr(value, -1, NumberFormatInfo.GetInstance(provider).NegativeSign);
1889 }
1890 return UInt32ToDecStr((uint)value);
1891 }
1892 return FormatInt32Slow(value, hexMask, format, provider);
1893 unsafe static string FormatInt32Slow(int value, int hexMask, string format, IFormatProvider provider)
1894 {
1895 ReadOnlySpan<char> format2 = format;
1896 int digits;
1897 char c = ParseFormatSpecifier(format2, out digits);
1898 char c2 = (char)(c & 0xFFDFu);
1899 if ((c2 == 'G') ? (digits < 1) : (c2 == 'D'))
1900 {
1901 if (value < 0)
1902 {
1903 return NegativeInt32ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign);
1904 }
1905 return UInt32ToDecStr((uint)value, digits);
1906 }
1907 if (c2 == 'X')
1908 {
1909 return Int32ToHexStr(value & hexMask, GetHexBase(c), digits);
1910 }
1911 NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
1912 byte* digits2 = stackalloc byte[11];
1913 NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 11);
1914 Int32ToNumber(value, ref number);
1915 char* pointer = stackalloc char[32];
1917 if (c != 0)
1918 {
1919 NumberToString(ref sb, ref number, c, digits, instance);
1920 }
1921 else
1922 {
1923 NumberToStringFormat(ref sb, ref number, format2, instance);
1924 }
1925 return sb.ToString();
1926 }
1927 }
1928
1929 public static bool TryFormatInt32(int value, int hexMask, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
1930 {
1931 if (format.Length == 0)
1932 {
1933 if (value < 0)
1934 {
1935 return TryNegativeInt32ToDecStr(value, -1, NumberFormatInfo.GetInstance(provider).NegativeSign, destination, out charsWritten);
1936 }
1937 return TryUInt32ToDecStr((uint)value, -1, destination, out charsWritten);
1938 }
1939 return TryFormatInt32Slow(value, hexMask, format, provider, destination, out charsWritten);
1940 unsafe static bool TryFormatInt32Slow(int value, int hexMask, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
1941 {
1942 int digits;
1943 char c = ParseFormatSpecifier(format, out digits);
1944 char c2 = (char)(c & 0xFFDFu);
1945 if ((c2 == 'G') ? (digits < 1) : (c2 == 'D'))
1946 {
1947 if (value < 0)
1948 {
1949 return TryNegativeInt32ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign, destination, out charsWritten);
1950 }
1951 return TryUInt32ToDecStr((uint)value, digits, destination, out charsWritten);
1952 }
1953 if (c2 == 'X')
1954 {
1955 return TryInt32ToHexStr(value & hexMask, GetHexBase(c), digits, destination, out charsWritten);
1956 }
1957 NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
1958 byte* digits2 = stackalloc byte[11];
1959 NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 11);
1960 Int32ToNumber(value, ref number);
1961 char* pointer = stackalloc char[32];
1963 if (c != 0)
1964 {
1965 NumberToString(ref sb, ref number, c, digits, instance);
1966 }
1967 else
1968 {
1969 NumberToStringFormat(ref sb, ref number, format, instance);
1970 }
1971 return sb.TryCopyTo(destination, out charsWritten);
1972 }
1973 }
1974
1975 public static string FormatUInt32(uint value, string format, IFormatProvider provider)
1976 {
1977 if (string.IsNullOrEmpty(format))
1978 {
1979 return UInt32ToDecStr(value);
1980 }
1981 return FormatUInt32Slow(value, format, provider);
1982 unsafe static string FormatUInt32Slow(uint value, string format, IFormatProvider provider)
1983 {
1984 ReadOnlySpan<char> format2 = format;
1985 int digits;
1986 char c = ParseFormatSpecifier(format2, out digits);
1987 char c2 = (char)(c & 0xFFDFu);
1988 if ((c2 == 'G') ? (digits < 1) : (c2 == 'D'))
1989 {
1990 return UInt32ToDecStr(value, digits);
1991 }
1992 if (c2 == 'X')
1993 {
1994 return Int32ToHexStr((int)value, GetHexBase(c), digits);
1995 }
1996 NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
1997 byte* digits2 = stackalloc byte[11];
1998 NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 11);
1999 UInt32ToNumber(value, ref number);
2000 char* pointer = stackalloc char[32];
2002 if (c != 0)
2003 {
2004 NumberToString(ref sb, ref number, c, digits, instance);
2005 }
2006 else
2007 {
2008 NumberToStringFormat(ref sb, ref number, format2, instance);
2009 }
2010 return sb.ToString();
2011 }
2012 }
2013
2014 public static bool TryFormatUInt32(uint value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
2015 {
2016 if (format.Length == 0)
2017 {
2018 return TryUInt32ToDecStr(value, -1, destination, out charsWritten);
2019 }
2020 return TryFormatUInt32Slow(value, format, provider, destination, out charsWritten);
2021 unsafe static bool TryFormatUInt32Slow(uint value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
2022 {
2023 int digits;
2024 char c = ParseFormatSpecifier(format, out digits);
2025 char c2 = (char)(c & 0xFFDFu);
2026 if ((c2 == 'G') ? (digits < 1) : (c2 == 'D'))
2027 {
2028 return TryUInt32ToDecStr(value, digits, destination, out charsWritten);
2029 }
2030 if (c2 == 'X')
2031 {
2032 return TryInt32ToHexStr((int)value, GetHexBase(c), digits, destination, out charsWritten);
2033 }
2034 NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
2035 byte* digits2 = stackalloc byte[11];
2036 NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 11);
2037 UInt32ToNumber(value, ref number);
2038 char* pointer = stackalloc char[32];
2040 if (c != 0)
2041 {
2042 NumberToString(ref sb, ref number, c, digits, instance);
2043 }
2044 else
2045 {
2046 NumberToStringFormat(ref sb, ref number, format, instance);
2047 }
2048 return sb.TryCopyTo(destination, out charsWritten);
2049 }
2050 }
2051
2052 public static string FormatInt64(long value, string format, IFormatProvider provider)
2053 {
2054 if (string.IsNullOrEmpty(format))
2055 {
2056 if (value < 0)
2057 {
2058 return NegativeInt64ToDecStr(value, -1, NumberFormatInfo.GetInstance(provider).NegativeSign);
2059 }
2060 return UInt64ToDecStr((ulong)value, -1);
2061 }
2062 return FormatInt64Slow(value, format, provider);
2063 unsafe static string FormatInt64Slow(long value, string format, IFormatProvider provider)
2064 {
2065 ReadOnlySpan<char> format2 = format;
2066 int digits;
2067 char c = ParseFormatSpecifier(format2, out digits);
2068 char c2 = (char)(c & 0xFFDFu);
2069 if ((c2 == 'G') ? (digits < 1) : (c2 == 'D'))
2070 {
2071 if (value < 0)
2072 {
2073 return NegativeInt64ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign);
2074 }
2075 return UInt64ToDecStr((ulong)value, digits);
2076 }
2077 if (c2 == 'X')
2078 {
2079 return Int64ToHexStr(value, GetHexBase(c), digits);
2080 }
2081 NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
2082 byte* digits2 = stackalloc byte[20];
2083 NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 20);
2084 Int64ToNumber(value, ref number);
2085 char* pointer = stackalloc char[32];
2087 if (c != 0)
2088 {
2089 NumberToString(ref sb, ref number, c, digits, instance);
2090 }
2091 else
2092 {
2093 NumberToStringFormat(ref sb, ref number, format2, instance);
2094 }
2095 return sb.ToString();
2096 }
2097 }
2098
2099 public static bool TryFormatInt64(long value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
2100 {
2101 if (format.Length == 0)
2102 {
2103 if (value < 0)
2104 {
2105 return TryNegativeInt64ToDecStr(value, -1, NumberFormatInfo.GetInstance(provider).NegativeSign, destination, out charsWritten);
2106 }
2107 return TryUInt64ToDecStr((ulong)value, -1, destination, out charsWritten);
2108 }
2109 return TryFormatInt64Slow(value, format, provider, destination, out charsWritten);
2110 unsafe static bool TryFormatInt64Slow(long value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
2111 {
2112 int digits;
2113 char c = ParseFormatSpecifier(format, out digits);
2114 char c2 = (char)(c & 0xFFDFu);
2115 if ((c2 == 'G') ? (digits < 1) : (c2 == 'D'))
2116 {
2117 if (value < 0)
2118 {
2119 return TryNegativeInt64ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign, destination, out charsWritten);
2120 }
2121 return TryUInt64ToDecStr((ulong)value, digits, destination, out charsWritten);
2122 }
2123 if (c2 == 'X')
2124 {
2125 return TryInt64ToHexStr(value, GetHexBase(c), digits, destination, out charsWritten);
2126 }
2127 NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
2128 byte* digits2 = stackalloc byte[20];
2129 NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 20);
2130 Int64ToNumber(value, ref number);
2131 char* pointer = stackalloc char[32];
2133 if (c != 0)
2134 {
2135 NumberToString(ref sb, ref number, c, digits, instance);
2136 }
2137 else
2138 {
2139 NumberToStringFormat(ref sb, ref number, format, instance);
2140 }
2141 return sb.TryCopyTo(destination, out charsWritten);
2142 }
2143 }
2144
2145 public static string FormatUInt64(ulong value, string format, IFormatProvider provider)
2146 {
2147 if (string.IsNullOrEmpty(format))
2148 {
2149 return UInt64ToDecStr(value, -1);
2150 }
2151 return FormatUInt64Slow(value, format, provider);
2152 unsafe static string FormatUInt64Slow(ulong value, string format, IFormatProvider provider)
2153 {
2154 ReadOnlySpan<char> format2 = format;
2155 int digits;
2156 char c = ParseFormatSpecifier(format2, out digits);
2157 char c2 = (char)(c & 0xFFDFu);
2158 if ((c2 == 'G') ? (digits < 1) : (c2 == 'D'))
2159 {
2160 return UInt64ToDecStr(value, digits);
2161 }
2162 if (c2 == 'X')
2163 {
2164 return Int64ToHexStr((long)value, GetHexBase(c), digits);
2165 }
2166 NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
2167 byte* digits2 = stackalloc byte[21];
2168 NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 21);
2169 UInt64ToNumber(value, ref number);
2170 char* pointer = stackalloc char[32];
2172 if (c != 0)
2173 {
2174 NumberToString(ref sb, ref number, c, digits, instance);
2175 }
2176 else
2177 {
2178 NumberToStringFormat(ref sb, ref number, format2, instance);
2179 }
2180 return sb.ToString();
2181 }
2182 }
2183
2184 public static bool TryFormatUInt64(ulong value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
2185 {
2186 if (format.Length == 0)
2187 {
2188 return TryUInt64ToDecStr(value, -1, destination, out charsWritten);
2189 }
2190 return TryFormatUInt64Slow(value, format, provider, destination, out charsWritten);
2191 unsafe static bool TryFormatUInt64Slow(ulong value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
2192 {
2193 int digits;
2194 char c = ParseFormatSpecifier(format, out digits);
2195 char c2 = (char)(c & 0xFFDFu);
2196 if ((c2 == 'G') ? (digits < 1) : (c2 == 'D'))
2197 {
2198 return TryUInt64ToDecStr(value, digits, destination, out charsWritten);
2199 }
2200 if (c2 == 'X')
2201 {
2202 return TryInt64ToHexStr((long)value, GetHexBase(c), digits, destination, out charsWritten);
2203 }
2204 NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
2205 byte* digits2 = stackalloc byte[21];
2206 NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 21);
2207 UInt64ToNumber(value, ref number);
2208 char* pointer = stackalloc char[32];
2210 if (c != 0)
2211 {
2212 NumberToString(ref sb, ref number, c, digits, instance);
2213 }
2214 else
2215 {
2216 NumberToStringFormat(ref sb, ref number, format, instance);
2217 }
2218 return sb.TryCopyTo(destination, out charsWritten);
2219 }
2220 }
2221
2222 [MethodImpl(MethodImplOptions.AggressiveInlining)]
2223 private unsafe static void Int32ToNumber(int value, ref NumberBuffer number)
2224 {
2225 number.DigitsCount = 10;
2226 if (value >= 0)
2227 {
2228 number.IsNegative = false;
2229 }
2230 else
2231 {
2232 number.IsNegative = true;
2233 value = -value;
2234 }
2235 byte* digitsPointer = number.GetDigitsPointer();
2236 byte* ptr = UInt32ToDecChars(digitsPointer + 10, (uint)value, 0);
2237 int num = (number.Scale = (number.DigitsCount = (int)(digitsPointer + 10 - ptr)));
2238 byte* digitsPointer2 = number.GetDigitsPointer();
2239 while (--num >= 0)
2240 {
2241 *(digitsPointer2++) = *(ptr++);
2242 }
2243 *digitsPointer2 = 0;
2244 }
2245
2246 public static string Int32ToDecStr(int value)
2247 {
2248 if (value < 0)
2249 {
2250 return NegativeInt32ToDecStr(value, -1, NumberFormatInfo.CurrentInfo.NegativeSign);
2251 }
2252 return UInt32ToDecStr((uint)value);
2253 }
2254
2255 private unsafe static string NegativeInt32ToDecStr(int value, int digits, string sNegative)
2256 {
2257 if (digits < 1)
2258 {
2259 digits = 1;
2260 }
2261 int num = Math.Max(digits, FormattingHelpers.CountDigits((uint)(-value))) + sNegative.Length;
2262 string text = string.FastAllocateString(num);
2263 fixed (char* ptr = text)
2264 {
2265 char* ptr2 = UInt32ToDecChars(ptr + num, (uint)(-value), digits);
2266 for (int num2 = sNegative.Length - 1; num2 >= 0; num2--)
2267 {
2268 *(--ptr2) = sNegative[num2];
2269 }
2270 }
2271 return text;
2272 }
2273
2274 private unsafe static bool TryNegativeInt32ToDecStr(int value, int digits, string sNegative, Span<char> destination, out int charsWritten)
2275 {
2276 if (digits < 1)
2277 {
2278 digits = 1;
2279 }
2280 int num = Math.Max(digits, FormattingHelpers.CountDigits((uint)(-value))) + sNegative.Length;
2281 if (num > destination.Length)
2282 {
2283 charsWritten = 0;
2284 return false;
2285 }
2286 charsWritten = num;
2287 fixed (char* ptr = &MemoryMarshal.GetReference(destination))
2288 {
2289 char* ptr2 = UInt32ToDecChars(ptr + num, (uint)(-value), digits);
2290 for (int num2 = sNegative.Length - 1; num2 >= 0; num2--)
2291 {
2292 *(--ptr2) = sNegative[num2];
2293 }
2294 }
2295 return true;
2296 }
2297
2298 private unsafe static string Int32ToHexStr(int value, char hexBase, int digits)
2299 {
2300 if (digits < 1)
2301 {
2302 digits = 1;
2303 }
2304 int num = Math.Max(digits, FormattingHelpers.CountHexDigits((uint)value));
2305 string text = string.FastAllocateString(num);
2306 fixed (char* ptr = text)
2307 {
2308 char* ptr2 = Int32ToHexChars(ptr + num, (uint)value, hexBase, digits);
2309 }
2310 return text;
2311 }
2312
2313 private unsafe static bool TryInt32ToHexStr(int value, char hexBase, int digits, Span<char> destination, out int charsWritten)
2314 {
2315 if (digits < 1)
2316 {
2317 digits = 1;
2318 }
2319 int num = Math.Max(digits, FormattingHelpers.CountHexDigits((uint)value));
2320 if (num > destination.Length)
2321 {
2322 charsWritten = 0;
2323 return false;
2324 }
2325 charsWritten = num;
2326 fixed (char* ptr = &MemoryMarshal.GetReference(destination))
2327 {
2328 char* ptr2 = Int32ToHexChars(ptr + num, (uint)value, hexBase, digits);
2329 }
2330 return true;
2331 }
2332
2333 private unsafe static char* Int32ToHexChars(char* buffer, uint value, int hexBase, int digits)
2334 {
2335 while (--digits >= 0 || value != 0)
2336 {
2337 byte b = (byte)(value & 0xFu);
2338 *(--buffer) = (char)(b + ((b < 10) ? 48 : hexBase));
2339 value >>= 4;
2340 }
2341 return buffer;
2342 }
2343
2344 [MethodImpl(MethodImplOptions.AggressiveInlining)]
2345 private unsafe static void UInt32ToNumber(uint value, ref NumberBuffer number)
2346 {
2347 number.DigitsCount = 10;
2348 number.IsNegative = false;
2349 byte* digitsPointer = number.GetDigitsPointer();
2350 byte* ptr = UInt32ToDecChars(digitsPointer + 10, value, 0);
2351 int num = (number.Scale = (number.DigitsCount = (int)(digitsPointer + 10 - ptr)));
2352 byte* digitsPointer2 = number.GetDigitsPointer();
2353 while (--num >= 0)
2354 {
2355 *(digitsPointer2++) = *(ptr++);
2356 }
2357 *digitsPointer2 = 0;
2358 }
2359
2360 internal unsafe static byte* UInt32ToDecChars(byte* bufferEnd, uint value, int digits)
2361 {
2362 while (--digits >= 0 || value != 0)
2363 {
2364 uint num;
2365 (value, num) = Math.DivRem(value, 10u);
2366 *(--bufferEnd) = (byte)(num + 48);
2367 }
2368 return bufferEnd;
2369 }
2370
2371 internal unsafe static char* UInt32ToDecChars(char* bufferEnd, uint value, int digits)
2372 {
2373 while (--digits >= 0 || value != 0)
2374 {
2375 uint num;
2376 (value, num) = Math.DivRem(value, 10u);
2377 *(--bufferEnd) = (char)(num + 48);
2378 }
2379 return bufferEnd;
2380 }
2381
2382 internal unsafe static string UInt32ToDecStr(uint value)
2383 {
2385 if (num == 1)
2386 {
2388 }
2389 string text = string.FastAllocateString(num);
2390 fixed (char* ptr = text)
2391 {
2392 char* ptr2 = ptr + num;
2393 do
2394 {
2395 uint num2;
2396 (value, num2) = Math.DivRem(value, 10u);
2397 *(--ptr2) = (char)(num2 + 48);
2398 }
2399 while (value != 0);
2400 }
2401 return text;
2402 }
2403
2404 private unsafe static string UInt32ToDecStr(uint value, int digits)
2405 {
2406 if (digits <= 1)
2407 {
2408 return UInt32ToDecStr(value);
2409 }
2410 int num = Math.Max(digits, FormattingHelpers.CountDigits(value));
2411 string text = string.FastAllocateString(num);
2412 fixed (char* ptr = text)
2413 {
2414 char* bufferEnd = ptr + num;
2415 bufferEnd = UInt32ToDecChars(bufferEnd, value, digits);
2416 }
2417 return text;
2418 }
2419
2420 private unsafe static bool TryUInt32ToDecStr(uint value, int digits, Span<char> destination, out int charsWritten)
2421 {
2422 int num = Math.Max(digits, FormattingHelpers.CountDigits(value));
2423 if (num > destination.Length)
2424 {
2425 charsWritten = 0;
2426 return false;
2427 }
2428 charsWritten = num;
2429 fixed (char* ptr = &MemoryMarshal.GetReference(destination))
2430 {
2431 char* ptr2 = ptr + num;
2432 if (digits <= 1)
2433 {
2434 do
2435 {
2436 uint num2;
2437 (value, num2) = Math.DivRem(value, 10u);
2438 *(--ptr2) = (char)(num2 + 48);
2439 }
2440 while (value != 0);
2441 }
2442 else
2443 {
2444 ptr2 = UInt32ToDecChars(ptr2, value, digits);
2445 }
2446 }
2447 return true;
2448 }
2449
2450 private unsafe static void Int64ToNumber(long input, ref NumberBuffer number)
2451 {
2452 ulong value = (ulong)input;
2453 number.IsNegative = input < 0;
2454 number.DigitsCount = 19;
2455 if (number.IsNegative)
2456 {
2457 value = (ulong)(-input);
2458 }
2459 byte* digitsPointer = number.GetDigitsPointer();
2460 byte* bufferEnd = digitsPointer + 19;
2461 while (High32(value) != 0)
2462 {
2463 bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9);
2464 }
2465 bufferEnd = UInt32ToDecChars(bufferEnd, Low32(value), 0);
2466 int num = (number.Scale = (number.DigitsCount = (int)(digitsPointer + 19 - bufferEnd)));
2467 byte* digitsPointer2 = number.GetDigitsPointer();
2468 while (--num >= 0)
2469 {
2470 *(digitsPointer2++) = *(bufferEnd++);
2471 }
2472 *digitsPointer2 = 0;
2473 }
2474
2475 public static string Int64ToDecStr(long value)
2476 {
2477 if (value < 0)
2478 {
2479 return NegativeInt64ToDecStr(value, -1, NumberFormatInfo.CurrentInfo.NegativeSign);
2480 }
2481 return UInt64ToDecStr((ulong)value, -1);
2482 }
2483
2484 private unsafe static string NegativeInt64ToDecStr(long input, int digits, string sNegative)
2485 {
2486 if (digits < 1)
2487 {
2488 digits = 1;
2489 }
2490 ulong value = (ulong)(-input);
2491 int num = Math.Max(digits, FormattingHelpers.CountDigits(value)) + sNegative.Length;
2492 string text = string.FastAllocateString(num);
2493 fixed (char* ptr = text)
2494 {
2495 char* bufferEnd = ptr + num;
2496 while (High32(value) != 0)
2497 {
2498 bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9);
2499 digits -= 9;
2500 }
2501 bufferEnd = UInt32ToDecChars(bufferEnd, Low32(value), digits);
2502 for (int num2 = sNegative.Length - 1; num2 >= 0; num2--)
2503 {
2504 *(--bufferEnd) = sNegative[num2];
2505 }
2506 }
2507 return text;
2508 }
2509
2510 private unsafe static bool TryNegativeInt64ToDecStr(long input, int digits, string sNegative, Span<char> destination, out int charsWritten)
2511 {
2512 if (digits < 1)
2513 {
2514 digits = 1;
2515 }
2516 ulong value = (ulong)(-input);
2517 int num = Math.Max(digits, FormattingHelpers.CountDigits((ulong)(-input))) + sNegative.Length;
2518 if (num > destination.Length)
2519 {
2520 charsWritten = 0;
2521 return false;
2522 }
2523 charsWritten = num;
2524 fixed (char* ptr = &MemoryMarshal.GetReference(destination))
2525 {
2526 char* bufferEnd = ptr + num;
2527 while (High32(value) != 0)
2528 {
2529 bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9);
2530 digits -= 9;
2531 }
2532 bufferEnd = UInt32ToDecChars(bufferEnd, Low32(value), digits);
2533 for (int num2 = sNegative.Length - 1; num2 >= 0; num2--)
2534 {
2535 *(--bufferEnd) = sNegative[num2];
2536 }
2537 }
2538 return true;
2539 }
2540
2541 private unsafe static string Int64ToHexStr(long value, char hexBase, int digits)
2542 {
2543 int num = Math.Max(digits, FormattingHelpers.CountHexDigits((ulong)value));
2544 string text = string.FastAllocateString(num);
2545 fixed (char* ptr = text)
2546 {
2547 char* buffer = ptr + num;
2548 if (High32((ulong)value) != 0)
2549 {
2550 buffer = Int32ToHexChars(buffer, Low32((ulong)value), hexBase, 8);
2551 buffer = Int32ToHexChars(buffer, High32((ulong)value), hexBase, digits - 8);
2552 }
2553 else
2554 {
2555 buffer = Int32ToHexChars(buffer, Low32((ulong)value), hexBase, Math.Max(digits, 1));
2556 }
2557 }
2558 return text;
2559 }
2560
2561 private unsafe static bool TryInt64ToHexStr(long value, char hexBase, int digits, Span<char> destination, out int charsWritten)
2562 {
2563 int num = Math.Max(digits, FormattingHelpers.CountHexDigits((ulong)value));
2564 if (num > destination.Length)
2565 {
2566 charsWritten = 0;
2567 return false;
2568 }
2569 charsWritten = num;
2570 fixed (char* ptr = &MemoryMarshal.GetReference(destination))
2571 {
2572 char* buffer = ptr + num;
2573 if (High32((ulong)value) != 0)
2574 {
2575 buffer = Int32ToHexChars(buffer, Low32((ulong)value), hexBase, 8);
2576 buffer = Int32ToHexChars(buffer, High32((ulong)value), hexBase, digits - 8);
2577 }
2578 else
2579 {
2580 buffer = Int32ToHexChars(buffer, Low32((ulong)value), hexBase, Math.Max(digits, 1));
2581 }
2582 }
2583 return true;
2584 }
2585
2586 private unsafe static void UInt64ToNumber(ulong value, ref NumberBuffer number)
2587 {
2588 number.DigitsCount = 20;
2589 number.IsNegative = false;
2590 byte* digitsPointer = number.GetDigitsPointer();
2591 byte* bufferEnd = digitsPointer + 20;
2592 while (High32(value) != 0)
2593 {
2594 bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9);
2595 }
2596 bufferEnd = UInt32ToDecChars(bufferEnd, Low32(value), 0);
2597 int num = (number.Scale = (number.DigitsCount = (int)(digitsPointer + 20 - bufferEnd)));
2598 byte* digitsPointer2 = number.GetDigitsPointer();
2599 while (--num >= 0)
2600 {
2601 *(digitsPointer2++) = *(bufferEnd++);
2602 }
2603 *digitsPointer2 = 0;
2604 }
2605
2606 internal unsafe static string UInt64ToDecStr(ulong value, int digits)
2607 {
2608 if (digits < 1)
2609 {
2610 digits = 1;
2611 }
2612 int num = Math.Max(digits, FormattingHelpers.CountDigits(value));
2613 if (num == 1)
2614 {
2616 }
2617 string text = string.FastAllocateString(num);
2618 fixed (char* ptr = text)
2619 {
2620 char* bufferEnd = ptr + num;
2621 while (High32(value) != 0)
2622 {
2623 bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9);
2624 digits -= 9;
2625 }
2626 bufferEnd = UInt32ToDecChars(bufferEnd, Low32(value), digits);
2627 }
2628 return text;
2629 }
2630
2631 private unsafe static bool TryUInt64ToDecStr(ulong value, int digits, Span<char> destination, out int charsWritten)
2632 {
2633 if (digits < 1)
2634 {
2635 digits = 1;
2636 }
2637 int num = Math.Max(digits, FormattingHelpers.CountDigits(value));
2638 if (num > destination.Length)
2639 {
2640 charsWritten = 0;
2641 return false;
2642 }
2643 charsWritten = num;
2644 fixed (char* ptr = &MemoryMarshal.GetReference(destination))
2645 {
2646 char* bufferEnd = ptr + num;
2647 while (High32(value) != 0)
2648 {
2649 bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9);
2650 digits -= 9;
2651 }
2652 bufferEnd = UInt32ToDecChars(bufferEnd, Low32(value), digits);
2653 }
2654 return true;
2655 }
2656
2657 internal static char ParseFormatSpecifier(ReadOnlySpan<char> format, out int digits)
2658 {
2659 char c = '\0';
2660 if (format.Length > 0)
2661 {
2662 c = format[0];
2663 if ((uint)(c - 65) <= 25u || (uint)(c - 97) <= 25u)
2664 {
2665 if (format.Length == 1)
2666 {
2667 digits = -1;
2668 return c;
2669 }
2670 if (format.Length == 2)
2671 {
2672 int num = format[1] - 48;
2673 if ((uint)num < 10u)
2674 {
2675 digits = num;
2676 return c;
2677 }
2678 }
2679 else if (format.Length == 3)
2680 {
2681 int num2 = format[1] - 48;
2682 int num3 = format[2] - 48;
2683 if ((uint)num2 < 10u && (uint)num3 < 10u)
2684 {
2685 digits = num2 * 10 + num3;
2686 return c;
2687 }
2688 }
2689 int num4 = 0;
2690 int num5 = 1;
2691 while (num5 < format.Length && (uint)(format[num5] - 48) < 10u)
2692 {
2693 int num6 = num4 * 10 + format[num5++] - 48;
2694 if (num6 < num4)
2695 {
2697 }
2698 num4 = num6;
2699 }
2700 if (num5 == format.Length || format[num5] == '\0')
2701 {
2702 digits = num4;
2703 return c;
2704 }
2705 }
2706 }
2707 digits = -1;
2708 if (format.Length != 0 && c != 0)
2709 {
2710 return '\0';
2711 }
2712 return 'G';
2713 }
2714
2715 internal static void NumberToString(ref ValueStringBuilder sb, ref NumberBuffer number, char format, int nMaxDigits, NumberFormatInfo info)
2716 {
2717 bool isCorrectlyRounded = number.Kind == NumberBufferKind.FloatingPoint;
2718 bool bSuppressScientific;
2719 switch (format)
2720 {
2721 case 'C':
2722 case 'c':
2723 if (nMaxDigits < 0)
2724 {
2725 nMaxDigits = info.CurrencyDecimalDigits;
2726 }
2727 RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded);
2728 FormatCurrency(ref sb, ref number, nMaxDigits, info);
2729 return;
2730 case 'F':
2731 case 'f':
2732 if (nMaxDigits < 0)
2733 {
2734 nMaxDigits = info.NumberDecimalDigits;
2735 }
2736 RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded);
2737 if (number.IsNegative)
2738 {
2739 sb.Append(info.NegativeSign);
2740 }
2741 FormatFixed(ref sb, ref number, nMaxDigits, null, info.NumberDecimalSeparator, null);
2742 return;
2743 case 'N':
2744 case 'n':
2745 if (nMaxDigits < 0)
2746 {
2747 nMaxDigits = info.NumberDecimalDigits;
2748 }
2749 RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded);
2750 FormatNumber(ref sb, ref number, nMaxDigits, info);
2751 return;
2752 case 'E':
2753 case 'e':
2754 if (nMaxDigits < 0)
2755 {
2756 nMaxDigits = 6;
2757 }
2758 nMaxDigits++;
2759 RoundNumber(ref number, nMaxDigits, isCorrectlyRounded);
2760 if (number.IsNegative)
2761 {
2762 sb.Append(info.NegativeSign);
2763 }
2764 FormatScientific(ref sb, ref number, nMaxDigits, info, format);
2765 return;
2766 case 'G':
2767 case 'g':
2768 bSuppressScientific = false;
2769 if (nMaxDigits < 1)
2770 {
2771 if (number.Kind == NumberBufferKind.Decimal && nMaxDigits == -1)
2772 {
2773 bSuppressScientific = true;
2774 if (number.Digits[0] != 0)
2775 {
2776 goto IL_0189;
2777 }
2778 goto IL_019e;
2779 }
2780 nMaxDigits = number.DigitsCount;
2781 }
2782 RoundNumber(ref number, nMaxDigits, isCorrectlyRounded);
2783 goto IL_0189;
2784 case 'P':
2785 case 'p':
2786 if (nMaxDigits < 0)
2787 {
2788 nMaxDigits = info.PercentDecimalDigits;
2789 }
2790 number.Scale += 2;
2791 RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded);
2792 FormatPercent(ref sb, ref number, nMaxDigits, info);
2793 return;
2794 case 'R':
2795 case 'r':
2796 {
2797 if (number.Kind != NumberBufferKind.FloatingPoint)
2798 {
2799 break;
2800 }
2801 format = (char)(format - 11);
2802 goto case 'G';
2803 }
2804 IL_0189:
2805 if (number.IsNegative)
2806 {
2807 sb.Append(info.NegativeSign);
2808 }
2809 goto IL_019e;
2810 IL_019e:
2811 FormatGeneral(ref sb, ref number, nMaxDigits, info, (char)(format - 2), bSuppressScientific);
2812 return;
2813 }
2815 }
2816
2818 {
2819 int num = 0;
2820 byte* digitsPointer = number.GetDigitsPointer();
2821 int num2 = FindSection(format, (*digitsPointer == 0) ? 2 : (number.IsNegative ? 1 : 0));
2822 int num3;
2823 int num4;
2824 bool flag;
2825 bool flag2;
2826 int num5;
2827 int num6;
2828 int num9;
2829 while (true)
2830 {
2831 num3 = 0;
2832 num4 = -1;
2833 num5 = int.MaxValue;
2834 num6 = 0;
2835 flag = false;
2836 int num7 = -1;
2837 flag2 = false;
2838 int num8 = 0;
2839 num9 = num2;
2840 fixed (char* ptr = &MemoryMarshal.GetReference(format))
2841 {
2842 char c;
2843 while (num9 < format.Length && (c = ptr[num9++]) != 0)
2844 {
2845 switch (c)
2846 {
2847 case ';':
2848 break;
2849 case '#':
2850 num3++;
2851 continue;
2852 case '0':
2853 if (num5 == int.MaxValue)
2854 {
2855 num5 = num3;
2856 }
2857 num3++;
2858 num6 = num3;
2859 continue;
2860 case '.':
2861 if (num4 < 0)
2862 {
2863 num4 = num3;
2864 }
2865 continue;
2866 case ',':
2867 if (num3 <= 0 || num4 >= 0)
2868 {
2869 continue;
2870 }
2871 if (num7 >= 0)
2872 {
2873 if (num7 == num3)
2874 {
2875 num++;
2876 continue;
2877 }
2878 flag2 = true;
2879 }
2880 num7 = num3;
2881 num = 1;
2882 continue;
2883 case '%':
2884 num8 += 2;
2885 continue;
2886 case '‰':
2887 num8 += 3;
2888 continue;
2889 case '"':
2890 case '\'':
2891 while (num9 < format.Length && ptr[num9] != 0 && ptr[num9++] != c)
2892 {
2893 }
2894 continue;
2895 case '\\':
2896 if (num9 < format.Length && ptr[num9] != 0)
2897 {
2898 num9++;
2899 }
2900 continue;
2901 case 'E':
2902 case 'e':
2903 if ((num9 < format.Length && ptr[num9] == '0') || (num9 + 1 < format.Length && (ptr[num9] == '+' || ptr[num9] == '-') && ptr[num9 + 1] == '0'))
2904 {
2905 while (++num9 < format.Length && ptr[num9] == '0')
2906 {
2907 }
2908 flag = true;
2909 }
2910 continue;
2911 default:
2912 continue;
2913 }
2914 break;
2915 }
2916 }
2917 if (num4 < 0)
2918 {
2919 num4 = num3;
2920 }
2921 if (num7 >= 0)
2922 {
2923 if (num7 == num4)
2924 {
2925 num8 -= num * 3;
2926 }
2927 else
2928 {
2929 flag2 = true;
2930 }
2931 }
2932 if (*digitsPointer != 0)
2933 {
2934 number.Scale += num8;
2935 int pos = (flag ? num3 : (number.Scale + num3 - num4));
2936 RoundNumber(ref number, pos, isCorrectlyRounded: false);
2937 if (*digitsPointer != 0)
2938 {
2939 break;
2940 }
2941 num9 = FindSection(format, 2);
2942 if (num9 == num2)
2943 {
2944 break;
2945 }
2946 num2 = num9;
2947 continue;
2948 }
2949 if (number.Kind != NumberBufferKind.FloatingPoint)
2950 {
2951 number.IsNegative = false;
2952 }
2953 number.Scale = 0;
2954 break;
2955 }
2956 num5 = ((num5 < num4) ? (num4 - num5) : 0);
2957 num6 = ((num6 > num4) ? (num4 - num6) : 0);
2958 int num10;
2959 int num11;
2960 if (flag)
2961 {
2962 num10 = num4;
2963 num11 = 0;
2964 }
2965 else
2966 {
2967 num10 = ((number.Scale > num4) ? number.Scale : num4);
2968 num11 = number.Scale - num4;
2969 }
2970 num9 = num2;
2971 Span<int> span = stackalloc int[4];
2972 int num12 = -1;
2973 if (flag2 && info.NumberGroupSeparator.Length > 0)
2974 {
2975 int[] numberGroupSizes = info._numberGroupSizes;
2976 int num13 = 0;
2977 int i = 0;
2978 int num14 = numberGroupSizes.Length;
2979 if (num14 != 0)
2980 {
2981 i = numberGroupSizes[num13];
2982 }
2983 int num15 = i;
2984 int num16 = num10 + ((num11 < 0) ? num11 : 0);
2985 for (int num17 = ((num5 > num16) ? num5 : num16); num17 > i; i += num15)
2986 {
2987 if (num15 == 0)
2988 {
2989 break;
2990 }
2991 num12++;
2992 if (num12 >= span.Length)
2993 {
2994 int[] array = new int[span.Length * 2];
2995 span.CopyTo(array);
2996 span = array;
2997 }
2998 span[num12] = i;
2999 if (num13 < num14 - 1)
3000 {
3001 num13++;
3002 num15 = numberGroupSizes[num13];
3003 }
3004 }
3005 }
3006 if (number.IsNegative && num2 == 0 && number.Scale != 0)
3007 {
3008 sb.Append(info.NegativeSign);
3009 }
3010 bool flag3 = false;
3011 fixed (char* ptr3 = &MemoryMarshal.GetReference(format))
3012 {
3013 byte* ptr2 = digitsPointer;
3014 char c;
3015 while (num9 < format.Length && (c = ptr3[num9++]) != 0 && c != ';')
3016 {
3017 if (num11 > 0 && (c == '#' || c == '.' || c == '0'))
3018 {
3019 while (num11 > 0)
3020 {
3021 sb.Append((char)((*ptr2 != 0) ? (*(ptr2++)) : 48));
3022 if (flag2 && num10 > 1 && num12 >= 0 && num10 == span[num12] + 1)
3023 {
3024 sb.Append(info.NumberGroupSeparator);
3025 num12--;
3026 }
3027 num10--;
3028 num11--;
3029 }
3030 }
3031 switch (c)
3032 {
3033 case '#':
3034 case '0':
3035 if (num11 < 0)
3036 {
3037 num11++;
3038 c = ((num10 <= num5) ? '0' : '\0');
3039 }
3040 else
3041 {
3042 c = ((*ptr2 != 0) ? ((char)(*(ptr2++))) : ((num10 > num6) ? '0' : '\0'));
3043 }
3044 if (c != 0)
3045 {
3046 sb.Append(c);
3047 if (flag2 && num10 > 1 && num12 >= 0 && num10 == span[num12] + 1)
3048 {
3049 sb.Append(info.NumberGroupSeparator);
3050 num12--;
3051 }
3052 }
3053 num10--;
3054 break;
3055 case '.':
3056 if (!(num10 != 0 || flag3) && (num6 < 0 || (num4 < num3 && *ptr2 != 0)))
3057 {
3058 sb.Append(info.NumberDecimalSeparator);
3059 flag3 = true;
3060 }
3061 break;
3062 case '‰':
3063 sb.Append(info.PerMilleSymbol);
3064 break;
3065 case '%':
3066 sb.Append(info.PercentSymbol);
3067 break;
3068 case '"':
3069 case '\'':
3070 while (num9 < format.Length && ptr3[num9] != 0 && ptr3[num9] != c)
3071 {
3072 sb.Append(ptr3[num9++]);
3073 }
3074 if (num9 < format.Length && ptr3[num9] != 0)
3075 {
3076 num9++;
3077 }
3078 break;
3079 case '\\':
3080 if (num9 < format.Length && ptr3[num9] != 0)
3081 {
3082 sb.Append(ptr3[num9++]);
3083 }
3084 break;
3085 case 'E':
3086 case 'e':
3087 {
3088 bool positiveSign = false;
3089 int num18 = 0;
3090 if (flag)
3091 {
3092 if (num9 < format.Length && ptr3[num9] == '0')
3093 {
3094 num18++;
3095 }
3096 else if (num9 + 1 < format.Length && ptr3[num9] == '+' && ptr3[num9 + 1] == '0')
3097 {
3098 positiveSign = true;
3099 }
3100 else if (num9 + 1 >= format.Length || ptr3[num9] != '-' || ptr3[num9 + 1] != '0')
3101 {
3102 sb.Append(c);
3103 break;
3104 }
3105 while (++num9 < format.Length && ptr3[num9] == '0')
3106 {
3107 num18++;
3108 }
3109 if (num18 > 10)
3110 {
3111 num18 = 10;
3112 }
3113 int value = ((*digitsPointer != 0) ? (number.Scale - num4) : 0);
3114 FormatExponent(ref sb, info, value, c, num18, positiveSign);
3115 flag = false;
3116 break;
3117 }
3118 sb.Append(c);
3119 if (num9 < format.Length)
3120 {
3121 if (ptr3[num9] == '+' || ptr3[num9] == '-')
3122 {
3123 sb.Append(ptr3[num9++]);
3124 }
3125 while (num9 < format.Length && ptr3[num9] == '0')
3126 {
3127 sb.Append(ptr3[num9++]);
3128 }
3129 }
3130 break;
3131 }
3132 default:
3133 sb.Append(c);
3134 break;
3135 case ',':
3136 break;
3137 }
3138 }
3139 }
3140 if (number.IsNegative && num2 == 0 && number.Scale == 0 && sb.Length > 0)
3141 {
3142 sb.Insert(0, info.NegativeSign);
3143 }
3144 }
3145
3146 private static void FormatCurrency(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info)
3147 {
3148 string text = (number.IsNegative ? s_negCurrencyFormats[info.CurrencyNegativePattern] : s_posCurrencyFormats[info.CurrencyPositivePattern]);
3149 string text2 = text;
3150 foreach (char c in text2)
3151 {
3152 switch (c)
3153 {
3154 case '#':
3155 FormatFixed(ref sb, ref number, nMaxDigits, info._currencyGroupSizes, info.CurrencyDecimalSeparator, info.CurrencyGroupSeparator);
3156 break;
3157 case '-':
3158 sb.Append(info.NegativeSign);
3159 break;
3160 case '$':
3161 sb.Append(info.CurrencySymbol);
3162 break;
3163 default:
3164 sb.Append(c);
3165 break;
3166 }
3167 }
3168 }
3169
3170 private unsafe static void FormatFixed(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, int[] groupDigits, string sDecimal, string sGroup)
3171 {
3172 int num = number.Scale;
3173 byte* ptr = number.GetDigitsPointer();
3174 if (num > 0)
3175 {
3176 if (groupDigits != null)
3177 {
3178 int num2 = 0;
3179 int num3 = num;
3180 int num4 = 0;
3181 if (groupDigits.Length != 0)
3182 {
3183 int num5 = groupDigits[num2];
3184 while (num > num5 && groupDigits[num2] != 0)
3185 {
3186 num3 += sGroup.Length;
3187 if (num2 < groupDigits.Length - 1)
3188 {
3189 num2++;
3190 }
3191 num5 += groupDigits[num2];
3192 if (num5 < 0 || num3 < 0)
3193 {
3194 throw new ArgumentOutOfRangeException();
3195 }
3196 }
3197 num4 = ((num5 != 0) ? groupDigits[0] : 0);
3198 }
3199 num2 = 0;
3200 int num6 = 0;
3201 int digitsCount = number.DigitsCount;
3202 int num7 = ((num < digitsCount) ? num : digitsCount);
3203 fixed (char* ptr2 = &MemoryMarshal.GetReference(sb.AppendSpan(num3)))
3204 {
3205 char* ptr3 = ptr2 + num3 - 1;
3206 for (int num8 = num - 1; num8 >= 0; num8--)
3207 {
3208 *(ptr3--) = (char)((num8 < num7) ? ptr[num8] : 48);
3209 if (num4 > 0)
3210 {
3211 num6++;
3212 if (num6 == num4 && num8 != 0)
3213 {
3214 for (int num9 = sGroup.Length - 1; num9 >= 0; num9--)
3215 {
3216 *(ptr3--) = sGroup[num9];
3217 }
3218 if (num2 < groupDigits.Length - 1)
3219 {
3220 num2++;
3221 num4 = groupDigits[num2];
3222 }
3223 num6 = 0;
3224 }
3225 }
3226 }
3227 ptr += num7;
3228 }
3229 }
3230 else
3231 {
3232 do
3233 {
3234 sb.Append((char)((*ptr != 0) ? (*(ptr++)) : 48));
3235 }
3236 while (--num > 0);
3237 }
3238 }
3239 else
3240 {
3241 sb.Append('0');
3242 }
3243 if (nMaxDigits > 0)
3244 {
3245 sb.Append(sDecimal);
3246 if (num < 0 && nMaxDigits > 0)
3247 {
3248 int num10 = Math.Min(-num, nMaxDigits);
3249 sb.Append('0', num10);
3250 num += num10;
3251 nMaxDigits -= num10;
3252 }
3253 while (nMaxDigits > 0)
3254 {
3255 sb.Append((char)((*ptr != 0) ? (*(ptr++)) : 48));
3256 nMaxDigits--;
3257 }
3258 }
3259 }
3260
3261 private static void FormatNumber(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info)
3262 {
3263 string text = (number.IsNegative ? s_negNumberFormats[info.NumberNegativePattern] : "#");
3264 string text2 = text;
3265 foreach (char c in text2)
3266 {
3267 switch (c)
3268 {
3269 case '#':
3270 FormatFixed(ref sb, ref number, nMaxDigits, info._numberGroupSizes, info.NumberDecimalSeparator, info.NumberGroupSeparator);
3271 break;
3272 case '-':
3273 sb.Append(info.NegativeSign);
3274 break;
3275 default:
3276 sb.Append(c);
3277 break;
3278 }
3279 }
3280 }
3281
3282 private unsafe static void FormatScientific(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info, char expChar)
3283 {
3284 byte* digitsPointer = number.GetDigitsPointer();
3285 sb.Append((char)((*digitsPointer != 0) ? (*(digitsPointer++)) : 48));
3286 if (nMaxDigits != 1)
3287 {
3288 sb.Append(info.NumberDecimalSeparator);
3289 }
3290 while (--nMaxDigits > 0)
3291 {
3292 sb.Append((char)((*digitsPointer != 0) ? (*(digitsPointer++)) : 48));
3293 }
3294 int value = ((number.Digits[0] != 0) ? (number.Scale - 1) : 0);
3295 FormatExponent(ref sb, info, value, expChar, 3, positiveSign: true);
3296 }
3297
3298 private unsafe static void FormatExponent(ref ValueStringBuilder sb, NumberFormatInfo info, int value, char expChar, int minDigits, bool positiveSign)
3299 {
3300 sb.Append(expChar);
3301 if (value < 0)
3302 {
3303 sb.Append(info.NegativeSign);
3304 value = -value;
3305 }
3306 else if (positiveSign)
3307 {
3308 sb.Append(info.PositiveSign);
3309 }
3310 char* ptr = stackalloc char[10];
3311 char* ptr2 = UInt32ToDecChars(ptr + 10, (uint)value, minDigits);
3312 sb.Append(ptr2, (int)(ptr + 10 - ptr2));
3313 }
3314
3315 private unsafe static void FormatGeneral(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info, char expChar, bool bSuppressScientific)
3316 {
3317 int i = number.Scale;
3318 bool flag = false;
3319 if (!bSuppressScientific && (i > nMaxDigits || i < -3))
3320 {
3321 i = 1;
3322 flag = true;
3323 }
3324 byte* digitsPointer = number.GetDigitsPointer();
3325 if (i > 0)
3326 {
3327 do
3328 {
3329 sb.Append((char)((*digitsPointer != 0) ? (*(digitsPointer++)) : 48));
3330 }
3331 while (--i > 0);
3332 }
3333 else
3334 {
3335 sb.Append('0');
3336 }
3337 if (*digitsPointer != 0 || i < 0)
3338 {
3339 sb.Append(info.NumberDecimalSeparator);
3340 for (; i < 0; i++)
3341 {
3342 sb.Append('0');
3343 }
3344 while (*digitsPointer != 0)
3345 {
3346 sb.Append((char)(*(digitsPointer++)));
3347 }
3348 }
3349 if (flag)
3350 {
3351 FormatExponent(ref sb, info, number.Scale - 1, expChar, 2, positiveSign: true);
3352 }
3353 }
3354
3355 private static void FormatPercent(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info)
3356 {
3357 string text = (number.IsNegative ? s_negPercentFormats[info.PercentNegativePattern] : s_posPercentFormats[info.PercentPositivePattern]);
3358 string text2 = text;
3359 foreach (char c in text2)
3360 {
3361 switch (c)
3362 {
3363 case '#':
3364 FormatFixed(ref sb, ref number, nMaxDigits, info._percentGroupSizes, info.PercentDecimalSeparator, info.PercentGroupSeparator);
3365 break;
3366 case '-':
3367 sb.Append(info.NegativeSign);
3368 break;
3369 case '%':
3370 sb.Append(info.PercentSymbol);
3371 break;
3372 default:
3373 sb.Append(c);
3374 break;
3375 }
3376 }
3377 }
3378
3379 internal unsafe static void RoundNumber(ref NumberBuffer number, int pos, bool isCorrectlyRounded)
3380 {
3381 byte* digitsPointer = number.GetDigitsPointer();
3382 int j;
3383 for (j = 0; j < pos && digitsPointer[j] != 0; j++)
3384 {
3385 }
3386 if (j == pos && ShouldRoundUp(digitsPointer, j, number.Kind, isCorrectlyRounded))
3387 {
3388 while (j > 0 && digitsPointer[j - 1] == 57)
3389 {
3390 j--;
3391 }
3392 if (j > 0)
3393 {
3394 byte* num = digitsPointer + (j - 1);
3395 (*num)++;
3396 }
3397 else
3398 {
3399 number.Scale++;
3400 *digitsPointer = 49;
3401 j = 1;
3402 }
3403 }
3404 else
3405 {
3406 while (j > 0 && digitsPointer[j - 1] == 48)
3407 {
3408 j--;
3409 }
3410 }
3411 if (j == 0)
3412 {
3413 if (number.Kind != NumberBufferKind.FloatingPoint)
3414 {
3415 number.IsNegative = false;
3416 }
3417 number.Scale = 0;
3418 }
3419 digitsPointer[j] = 0;
3420 number.DigitsCount = j;
3421 unsafe static bool ShouldRoundUp(byte* dig, int i, NumberBufferKind numberKind, bool isCorrectlyRounded)
3422 {
3423 byte b = dig[i];
3424 if (b == 0 || isCorrectlyRounded)
3425 {
3426 return false;
3427 }
3428 return b >= 53;
3429 }
3430 }
3431
3432 private unsafe static int FindSection(ReadOnlySpan<char> format, int section)
3433 {
3434 if (section == 0)
3435 {
3436 return 0;
3437 }
3438 fixed (char* ptr = &MemoryMarshal.GetReference(format))
3439 {
3440 int num = 0;
3441 while (true)
3442 {
3443 if (num >= format.Length)
3444 {
3445 return 0;
3446 }
3447 char c;
3448 char c2 = (c = ptr[num++]);
3449 if ((uint)c2 <= 34u)
3450 {
3451 if (c2 == '\0')
3452 {
3453 break;
3454 }
3455 if (c2 != '"')
3456 {
3457 continue;
3458 }
3459 }
3460 else if (c2 != '\'')
3461 {
3462 switch (c2)
3463 {
3464 default:
3465 continue;
3466 case '\\':
3467 if (num < format.Length && ptr[num] != 0)
3468 {
3469 num++;
3470 }
3471 continue;
3472 case ';':
3473 break;
3474 }
3475 if (--section == 0)
3476 {
3477 if (num >= format.Length || ptr[num] == '\0' || ptr[num] == ';')
3478 {
3479 break;
3480 }
3481 return num;
3482 }
3483 continue;
3484 }
3485 while (num < format.Length && ptr[num] != 0 && ptr[num++] != c)
3486 {
3487 }
3488 }
3489 return 0;
3490 }
3491 }
3492
3493 private static uint Low32(ulong value)
3494 {
3495 return (uint)value;
3496 }
3497
3498 private static uint High32(ulong value)
3499 {
3500 return (uint)((value & 0xFFFFFFFF00000000uL) >> 32);
3501 }
3502
3503 private static uint Int64DivMod1E9(ref ulong value)
3504 {
3505 uint result = (uint)(value % 1000000000);
3506 value /= 1000000000uL;
3507 return result;
3508 }
3509
3510 private static ulong ExtractFractionAndBiasedExponent(double value, out int exponent)
3511 {
3513 ulong num2 = num & 0xFFFFFFFFFFFFFuL;
3514 exponent = (int)(num >> 52) & 0x7FF;
3515 if (exponent != 0)
3516 {
3517 num2 |= 0x10000000000000uL;
3518 exponent -= 1075;
3519 }
3520 else
3521 {
3522 exponent = -1074;
3523 }
3524 return num2;
3525 }
3526
3527 private static ushort ExtractFractionAndBiasedExponent(Half value, out int exponent)
3528 {
3529 ushort num = BitConverter.HalfToUInt16Bits(value);
3530 ushort num2 = (ushort)(num & 0x3FFu);
3531 exponent = (num >> 10) & 0x1F;
3532 if (exponent != 0)
3533 {
3534 num2 = (ushort)(num2 | 0x400u);
3535 exponent -= 25;
3536 }
3537 else
3538 {
3539 exponent = -24;
3540 }
3541 return num2;
3542 }
3543
3544 private static uint ExtractFractionAndBiasedExponent(float value, out int exponent)
3545 {
3547 uint num2 = num & 0x7FFFFFu;
3548 exponent = (int)((num >> 23) & 0xFF);
3549 if (exponent != 0)
3550 {
3551 num2 |= 0x800000u;
3552 exponent -= 150;
3553 }
3554 else
3555 {
3556 exponent = -149;
3557 }
3558 return num2;
3559 }
3560
3561 private unsafe static void AccumulateDecimalDigitsIntoBigInteger(ref NumberBuffer number, uint firstIndex, uint lastIndex, out BigInteger result)
3562 {
3563 BigInteger.SetZero(out result);
3564 byte* ptr = number.GetDigitsPointer() + firstIndex;
3565 uint num = lastIndex - firstIndex;
3566 while (num != 0)
3567 {
3568 uint num2 = Math.Min(num, 9u);
3569 uint value = DigitsToUInt32(ptr, (int)num2);
3570 result.MultiplyPow10(num2);
3571 result.Add(value);
3572 ptr += num2;
3573 num -= num2;
3574 }
3575 }
3576
3577 private static ulong AssembleFloatingPointBits(in FloatingPointInfo info, ulong initialMantissa, int initialExponent, bool hasZeroTail)
3578 {
3579 uint num = BigInteger.CountSignificantBits(initialMantissa);
3580 int num2 = (int)(info.NormalMantissaBits - num);
3581 int num3 = initialExponent - num2;
3582 ulong num4 = initialMantissa;
3583 int num5 = num3;
3584 if (num3 > info.MaxBinaryExponent)
3585 {
3586 return info.InfinityBits;
3587 }
3588 if (num3 < info.MinBinaryExponent)
3589 {
3590 int num6 = num2 + num3 + info.ExponentBias - 1;
3591 num5 = -info.ExponentBias;
3592 if (num6 < 0)
3593 {
3594 num4 = RightShiftWithRounding(num4, -num6, hasZeroTail);
3595 if (num4 == 0L)
3596 {
3597 return info.ZeroBits;
3598 }
3599 if (num4 > info.DenormalMantissaMask)
3600 {
3601 num5 = initialExponent - (num6 + 1) - num2;
3602 }
3603 }
3604 else
3605 {
3606 num4 <<= num6;
3607 }
3608 }
3609 else if (num2 < 0)
3610 {
3611 num4 = RightShiftWithRounding(num4, -num2, hasZeroTail);
3612 if (num4 > info.NormalMantissaMask)
3613 {
3614 num4 >>= 1;
3615 num5++;
3616 if (num5 > info.MaxBinaryExponent)
3617 {
3618 return info.InfinityBits;
3619 }
3620 }
3621 }
3622 else if (num2 > 0)
3623 {
3624 num4 <<= num2;
3625 }
3626 num4 &= info.DenormalMantissaMask;
3627 ulong num7 = (ulong)((long)(num5 + info.ExponentBias) << (int)info.DenormalMantissaBits);
3628 return num7 | num4;
3629 }
3630
3631 private static ulong ConvertBigIntegerToFloatingPointBits(ref BigInteger value, in FloatingPointInfo info, uint integerBitsOfPrecision, bool hasNonZeroFractionalPart)
3632 {
3633 int denormalMantissaBits = info.DenormalMantissaBits;
3634 if (integerBitsOfPrecision <= 64)
3635 {
3636 return AssembleFloatingPointBits(in info, value.ToUInt64(), denormalMantissaBits, !hasNonZeroFractionalPart);
3637 }
3638 (uint Quotient, uint Remainder) tuple = Math.DivRem(integerBitsOfPrecision, 32u);
3639 uint item = tuple.Quotient;
3640 uint item2 = tuple.Remainder;
3641 uint num = item - 1;
3642 uint num2 = num - 1;
3643 int num3 = denormalMantissaBits + (int)(num2 * 32);
3644 bool flag = !hasNonZeroFractionalPart;
3645 ulong initialMantissa;
3646 if (item2 == 0)
3647 {
3648 initialMantissa = ((ulong)value.GetBlock(num) << 32) + value.GetBlock(num2);
3649 }
3650 else
3651 {
3652 int num4 = (int)item2;
3653 int num5 = 64 - num4;
3654 int num6 = num5 - 32;
3655 num3 += (int)item2;
3656 uint block = value.GetBlock(num2);
3657 uint num7 = block >> num4;
3658 ulong num8 = (ulong)value.GetBlock(num) << num6;
3659 ulong num9 = (ulong)value.GetBlock(item) << num5;
3660 initialMantissa = num9 + num8 + num7;
3661 uint num10 = (uint)((1 << (int)item2) - 1);
3662 flag = flag && (block & num10) == 0;
3663 }
3664 for (uint num11 = 0u; num11 != num2; num11++)
3665 {
3666 flag &= value.GetBlock(num11) == 0;
3667 }
3668 return AssembleFloatingPointBits(in info, initialMantissa, num3, flag);
3669 }
3670
3671 private unsafe static uint DigitsToUInt32(byte* p, int count)
3672 {
3673 byte* ptr = p + count;
3674 uint num = (uint)(*p - 48);
3675 for (p++; p < ptr; p++)
3676 {
3677 num = 10 * num + *p - 48;
3678 }
3679 return num;
3680 }
3681
3682 private unsafe static ulong DigitsToUInt64(byte* p, int count)
3683 {
3684 byte* ptr = p + count;
3685 ulong num = (ulong)(*p - 48);
3686 for (p++; p < ptr; p++)
3687 {
3688 num = 10 * num + *p - 48;
3689 }
3690 return num;
3691 }
3692
3693 private unsafe static ulong NumberToDoubleFloatingPointBits(ref NumberBuffer number, in FloatingPointInfo info)
3694 {
3695 uint digitsCount = (uint)number.DigitsCount;
3696 uint num = (uint)Math.Max(0, number.Scale);
3697 uint num2 = Math.Min(num, digitsCount);
3698 uint num3 = digitsCount - num2;
3699 uint num4 = (uint)Math.Abs(number.Scale - num2 - num3);
3700 byte* digitsPointer = number.GetDigitsPointer();
3701 if (digitsCount <= 15 && num4 <= 22)
3702 {
3703 double num5 = DigitsToUInt64(digitsPointer, (int)digitsCount);
3704 double num6 = s_Pow10DoubleTable[num4];
3705 num5 = ((num3 == 0) ? (num5 * num6) : (num5 / num6));
3706 return BitConverter.DoubleToUInt64Bits(num5);
3707 }
3708 return NumberToFloatingPointBitsSlow(ref number, in info, num, num2, num3);
3709 }
3710
3711 private unsafe static ushort NumberToHalfFloatingPointBits(ref NumberBuffer number, in FloatingPointInfo info)
3712 {
3713 uint digitsCount = (uint)number.DigitsCount;
3714 uint num = (uint)Math.Max(0, number.Scale);
3715 uint num2 = Math.Min(num, digitsCount);
3716 uint num3 = digitsCount - num2;
3717 uint num4 = (uint)Math.Abs(number.Scale - num2 - num3);
3718 byte* digitsPointer = number.GetDigitsPointer();
3719 if (digitsCount <= 7 && num4 <= 10)
3720 {
3721 float num5 = DigitsToUInt32(digitsPointer, (int)digitsCount);
3722 float num6 = s_Pow10SingleTable[num4];
3723 num5 = ((num3 == 0) ? (num5 * num6) : (num5 / num6));
3724 return BitConverter.HalfToUInt16Bits((Half)num5);
3725 }
3726 if (digitsCount <= 15 && num4 <= 22)
3727 {
3728 double num7 = DigitsToUInt64(digitsPointer, (int)digitsCount);
3729 double num8 = s_Pow10DoubleTable[num4];
3730 num7 = ((num3 == 0) ? (num7 * num8) : (num7 / num8));
3731 return BitConverter.HalfToUInt16Bits((Half)num7);
3732 }
3733 return (ushort)NumberToFloatingPointBitsSlow(ref number, in info, num, num2, num3);
3734 }
3735
3736 private unsafe static uint NumberToSingleFloatingPointBits(ref NumberBuffer number, in FloatingPointInfo info)
3737 {
3738 uint digitsCount = (uint)number.DigitsCount;
3739 uint num = (uint)Math.Max(0, number.Scale);
3740 uint num2 = Math.Min(num, digitsCount);
3741 uint num3 = digitsCount - num2;
3742 uint num4 = (uint)Math.Abs(number.Scale - num2 - num3);
3743 byte* digitsPointer = number.GetDigitsPointer();
3744 if (digitsCount <= 7 && num4 <= 10)
3745 {
3746 float num5 = DigitsToUInt32(digitsPointer, (int)digitsCount);
3747 float num6 = s_Pow10SingleTable[num4];
3748 num5 = ((num3 == 0) ? (num5 * num6) : (num5 / num6));
3749 return BitConverter.SingleToUInt32Bits(num5);
3750 }
3751 if (digitsCount <= 15 && num4 <= 22)
3752 {
3753 double num7 = DigitsToUInt64(digitsPointer, (int)digitsCount);
3754 double num8 = s_Pow10DoubleTable[num4];
3755 num7 = ((num3 == 0) ? (num7 * num8) : (num7 / num8));
3756 return BitConverter.SingleToUInt32Bits((float)num7);
3757 }
3758 return (uint)NumberToFloatingPointBitsSlow(ref number, in info, num, num2, num3);
3759 }
3760
3761 private static ulong NumberToFloatingPointBitsSlow(ref NumberBuffer number, in FloatingPointInfo info, uint positiveExponent, uint integerDigitsPresent, uint fractionalDigitsPresent)
3762 {
3763 uint num = (uint)(info.NormalMantissaBits + 1);
3764 uint digitsCount = (uint)number.DigitsCount;
3765 uint num2 = positiveExponent - integerDigitsPresent;
3766 uint lastIndex = digitsCount;
3767 AccumulateDecimalDigitsIntoBigInteger(ref number, 0u, integerDigitsPresent, out var result);
3768 if (num2 != 0)
3769 {
3770 if (num2 > info.OverflowDecimalExponent)
3771 {
3772 return info.InfinityBits;
3773 }
3774 result.MultiplyPow10(num2);
3775 }
3776 uint num3 = BigInteger.CountSignificantBits(ref result);
3777 if (num3 >= num || fractionalDigitsPresent == 0)
3778 {
3779 return ConvertBigIntegerToFloatingPointBits(ref result, in info, num3, fractionalDigitsPresent != 0);
3780 }
3781 uint num4 = fractionalDigitsPresent;
3782 if (number.Scale < 0)
3783 {
3784 num4 += (uint)(-number.Scale);
3785 }
3786 if (num3 == 0 && num4 - (int)digitsCount > info.OverflowDecimalExponent)
3787 {
3788 return info.ZeroBits;
3789 }
3790 AccumulateDecimalDigitsIntoBigInteger(ref number, integerDigitsPresent, lastIndex, out var result2);
3791 if (result2.IsZero())
3792 {
3793 return ConvertBigIntegerToFloatingPointBits(ref result, in info, num3, fractionalDigitsPresent != 0);
3794 }
3795 BigInteger.Pow10(num4, out var result3);
3796 uint num5 = BigInteger.CountSignificantBits(ref result2);
3797 uint num6 = BigInteger.CountSignificantBits(ref result3);
3798 uint num7 = 0u;
3799 if (num6 > num5)
3800 {
3801 num7 = num6 - num5;
3802 }
3803 if (num7 != 0)
3804 {
3805 result2.ShiftLeft(num7);
3806 }
3807 uint num8 = num - num3;
3808 uint num9 = num8;
3809 if (num3 != 0)
3810 {
3811 if (num7 > num9)
3812 {
3813 return ConvertBigIntegerToFloatingPointBits(ref result, in info, num3, fractionalDigitsPresent != 0);
3814 }
3815 num9 -= num7;
3816 }
3817 uint num10 = num7;
3818 if (BigInteger.Compare(ref result2, ref result3) < 0)
3819 {
3820 num10++;
3821 }
3822 result2.ShiftLeft(num9);
3823 BigInteger.DivRem(ref result2, ref result3, out var quo, out var rem);
3824 ulong num11 = quo.ToUInt64();
3825 bool flag = !number.HasNonZeroTail && rem.IsZero();
3826 uint num12 = BigInteger.CountSignificantBits(num11);
3827 if (num12 > num8)
3828 {
3829 int num13 = (int)(num12 - num8);
3830 flag = flag && (num11 & (ulong)((1L << num13) - 1)) == 0;
3831 num11 >>= num13;
3832 }
3833 ulong num14 = result.ToUInt64();
3834 ulong initialMantissa = (num14 << (int)num8) + num11;
3835 int initialExponent = (int)((num3 != 0) ? (num3 - 2) : (0 - num10 - 1));
3836 return AssembleFloatingPointBits(in info, initialMantissa, initialExponent, flag);
3837 }
3838
3839 private static ulong RightShiftWithRounding(ulong value, int shift, bool hasZeroTail)
3840 {
3841 if (shift >= 64)
3842 {
3843 return 0uL;
3844 }
3845 ulong num = (ulong)((1L << shift - 1) - 1);
3846 ulong num2 = (ulong)(1L << shift - 1);
3847 ulong num3 = (ulong)(1L << shift);
3848 bool lsbBit = (value & num3) != 0;
3849 bool roundBit = (value & num2) != 0;
3850 bool hasTailBits = !hasZeroTail || (value & num) != 0;
3851 return (value >> shift) + (ulong)(ShouldRoundUp(lsbBit, roundBit, hasTailBits) ? 1 : 0);
3852 }
3853
3854 private static bool ShouldRoundUp(bool lsbBit, bool roundBit, bool hasTailBits)
3855 {
3856 if (roundBit)
3857 {
3858 return hasTailBits || lsbBit;
3859 }
3860 return false;
3861 }
3862
3863 private unsafe static bool TryNumberToInt32(ref NumberBuffer number, ref int value)
3864 {
3865 int num = number.Scale;
3866 if (num > 10 || num < number.DigitsCount)
3867 {
3868 return false;
3869 }
3870 byte* digitsPointer = number.GetDigitsPointer();
3871 int num2 = 0;
3872 while (--num >= 0)
3873 {
3874 if ((uint)num2 > 214748364u)
3875 {
3876 return false;
3877 }
3878 num2 *= 10;
3879 if (*digitsPointer != 0)
3880 {
3881 num2 += *(digitsPointer++) - 48;
3882 }
3883 }
3884 if (number.IsNegative)
3885 {
3886 num2 = -num2;
3887 if (num2 > 0)
3888 {
3889 return false;
3890 }
3891 }
3892 else if (num2 < 0)
3893 {
3894 return false;
3895 }
3896 value = num2;
3897 return true;
3898 }
3899
3900 private unsafe static bool TryNumberToInt64(ref NumberBuffer number, ref long value)
3901 {
3902 int num = number.Scale;
3903 if (num > 19 || num < number.DigitsCount)
3904 {
3905 return false;
3906 }
3907 byte* digitsPointer = number.GetDigitsPointer();
3908 long num2 = 0L;
3909 while (--num >= 0)
3910 {
3911 if ((ulong)num2 > 922337203685477580uL)
3912 {
3913 return false;
3914 }
3915 num2 *= 10;
3916 if (*digitsPointer != 0)
3917 {
3918 num2 += *(digitsPointer++) - 48;
3919 }
3920 }
3921 if (number.IsNegative)
3922 {
3923 num2 = -num2;
3924 if (num2 > 0)
3925 {
3926 return false;
3927 }
3928 }
3929 else if (num2 < 0)
3930 {
3931 return false;
3932 }
3933 value = num2;
3934 return true;
3935 }
3936
3937 private unsafe static bool TryNumberToUInt32(ref NumberBuffer number, ref uint value)
3938 {
3939 int num = number.Scale;
3940 if (num > 10 || num < number.DigitsCount || number.IsNegative)
3941 {
3942 return false;
3943 }
3944 byte* digitsPointer = number.GetDigitsPointer();
3945 uint num2 = 0u;
3946 while (--num >= 0)
3947 {
3948 if (num2 > 429496729)
3949 {
3950 return false;
3951 }
3952 num2 *= 10;
3953 if (*digitsPointer != 0)
3954 {
3955 uint num3 = num2 + (uint)(*(digitsPointer++) - 48);
3956 if (num3 < num2)
3957 {
3958 return false;
3959 }
3960 num2 = num3;
3961 }
3962 }
3963 value = num2;
3964 return true;
3965 }
3966
3967 private unsafe static bool TryNumberToUInt64(ref NumberBuffer number, ref ulong value)
3968 {
3969 int num = number.Scale;
3970 if (num > 20 || num < number.DigitsCount || number.IsNegative)
3971 {
3972 return false;
3973 }
3974 byte* digitsPointer = number.GetDigitsPointer();
3975 ulong num2 = 0uL;
3976 while (--num >= 0)
3977 {
3978 if (num2 > 1844674407370955161L)
3979 {
3980 return false;
3981 }
3982 num2 *= 10;
3983 if (*digitsPointer != 0)
3984 {
3985 ulong num3 = num2 + (ulong)(*(digitsPointer++) - 48);
3986 if (num3 < num2)
3987 {
3988 return false;
3989 }
3990 num2 = num3;
3991 }
3992 }
3993 value = num2;
3994 return true;
3995 }
3996
3998 {
3999 int result;
4000 ParsingStatus parsingStatus = TryParseInt32(value, styles, info, out result);
4001 if (parsingStatus != 0)
4002 {
4003 ThrowOverflowOrFormatException(parsingStatus, TypeCode.Int32);
4004 }
4005 return result;
4006 }
4007
4009 {
4010 long result;
4011 ParsingStatus parsingStatus = TryParseInt64(value, styles, info, out result);
4012 if (parsingStatus != 0)
4013 {
4014 ThrowOverflowOrFormatException(parsingStatus, TypeCode.Int64);
4015 }
4016 return result;
4017 }
4018
4020 {
4021 uint result;
4022 ParsingStatus parsingStatus = TryParseUInt32(value, styles, info, out result);
4023 if (parsingStatus != 0)
4024 {
4025 ThrowOverflowOrFormatException(parsingStatus, TypeCode.UInt32);
4026 }
4027 return result;
4028 }
4029
4031 {
4032 ulong result;
4033 ParsingStatus parsingStatus = TryParseUInt64(value, styles, info, out result);
4034 if (parsingStatus != 0)
4035 {
4036 ThrowOverflowOrFormatException(parsingStatus, TypeCode.UInt64);
4037 }
4038 return result;
4039 }
4040
4041 private unsafe static bool TryParseNumber(ref char* str, char* strEnd, NumberStyles styles, ref NumberBuffer number, NumberFormatInfo info)
4042 {
4043 string text = null;
4044 bool flag = false;
4045 string value;
4046 string value2;
4047 if ((styles & NumberStyles.AllowCurrencySymbol) != 0)
4048 {
4049 text = info.CurrencySymbol;
4050 value = info.CurrencyDecimalSeparator;
4051 value2 = info.CurrencyGroupSeparator;
4052 flag = true;
4053 }
4054 else
4055 {
4056 value = info.NumberDecimalSeparator;
4057 value2 = info.NumberGroupSeparator;
4058 }
4059 int num = 0;
4060 char* ptr = str;
4061 char c = ((ptr < strEnd) ? (*ptr) : '\0');
4062 while (true)
4063 {
4064 if (!IsWhite(c) || (styles & NumberStyles.AllowLeadingWhite) == 0 || (((uint)num & (true ? 1u : 0u)) != 0 && (num & 0x20) == 0 && info.NumberNegativePattern != 2))
4065 {
4066 char* ptr2;
4067 if ((styles & NumberStyles.AllowLeadingSign) != 0 && (num & 1) == 0 && ((ptr2 = MatchChars(ptr, strEnd, info.PositiveSign)) != null || ((ptr2 = MatchNegativeSignChars(ptr, strEnd, info)) != null && (number.IsNegative = true))))
4068 {
4069 num |= 1;
4070 ptr = ptr2 - 1;
4071 }
4072 else if (c == '(' && (styles & NumberStyles.AllowParentheses) != 0 && (num & 1) == 0)
4073 {
4074 num |= 3;
4075 number.IsNegative = true;
4076 }
4077 else
4078 {
4079 if (text == null || (ptr2 = MatchChars(ptr, strEnd, text)) == null)
4080 {
4081 break;
4082 }
4083 num |= 0x20;
4084 text = null;
4085 ptr = ptr2 - 1;
4086 }
4087 }
4088 c = ((++ptr < strEnd) ? (*ptr) : '\0');
4089 }
4090 int num2 = 0;
4091 int num3 = 0;
4092 int num4 = number.Digits.Length - 1;
4093 int num5 = 0;
4094 while (true)
4095 {
4096 char* ptr2;
4097 if (IsDigit(c))
4098 {
4099 num |= 4;
4100 if (c != '0' || ((uint)num & 8u) != 0)
4101 {
4102 if (num2 < num4)
4103 {
4104 number.Digits[num2] = (byte)c;
4105 if (c != '0' || number.Kind != NumberBufferKind.Integer)
4106 {
4107 num3 = num2 + 1;
4108 }
4109 }
4110 else if (c != '0')
4111 {
4112 number.HasNonZeroTail = true;
4113 }
4114 if ((num & 0x10) == 0)
4115 {
4116 number.Scale++;
4117 }
4118 if (num2 < num4)
4119 {
4120 num5 = ((c == '0') ? (num5 + 1) : 0);
4121 }
4122 num2++;
4123 num |= 8;
4124 }
4125 else if (((uint)num & 0x10u) != 0)
4126 {
4127 number.Scale--;
4128 }
4129 }
4130 else if ((styles & NumberStyles.AllowDecimalPoint) != 0 && (num & 0x10) == 0 && ((ptr2 = MatchChars(ptr, strEnd, value)) != null || (flag && (num & 0x20) == 0 && (ptr2 = MatchChars(ptr, strEnd, info.NumberDecimalSeparator)) != null)))
4131 {
4132 num |= 0x10;
4133 ptr = ptr2 - 1;
4134 }
4135 else
4136 {
4137 if ((styles & NumberStyles.AllowThousands) == 0 || (num & 4) == 0 || ((uint)num & 0x10u) != 0 || ((ptr2 = MatchChars(ptr, strEnd, value2)) == null && (!flag || ((uint)num & 0x20u) != 0 || (ptr2 = MatchChars(ptr, strEnd, info.NumberGroupSeparator)) == null)))
4138 {
4139 break;
4140 }
4141 ptr = ptr2 - 1;
4142 }
4143 c = ((++ptr < strEnd) ? (*ptr) : '\0');
4144 }
4145 bool flag2 = false;
4146 number.DigitsCount = num3;
4147 number.Digits[num3] = 0;
4148 if (((uint)num & 4u) != 0)
4149 {
4150 if ((c == 'E' || c == 'e') && (styles & NumberStyles.AllowExponent) != 0)
4151 {
4152 char* ptr3 = ptr;
4153 c = ((++ptr < strEnd) ? (*ptr) : '\0');
4154 char* ptr2;
4155 if ((ptr2 = MatchChars(ptr, strEnd, info._positiveSign)) != null)
4156 {
4157 c = (((ptr = ptr2) < strEnd) ? (*ptr) : '\0');
4158 }
4159 else if ((ptr2 = MatchNegativeSignChars(ptr, strEnd, info)) != null)
4160 {
4161 c = (((ptr = ptr2) < strEnd) ? (*ptr) : '\0');
4162 flag2 = true;
4163 }
4164 if (IsDigit(c))
4165 {
4166 int num6 = 0;
4167 do
4168 {
4169 num6 = num6 * 10 + (c - 48);
4170 c = ((++ptr < strEnd) ? (*ptr) : '\0');
4171 if (num6 > 1000)
4172 {
4173 num6 = 9999;
4174 while (IsDigit(c))
4175 {
4176 c = ((++ptr < strEnd) ? (*ptr) : '\0');
4177 }
4178 }
4179 }
4180 while (IsDigit(c));
4181 if (flag2)
4182 {
4183 num6 = -num6;
4184 }
4185 number.Scale += num6;
4186 }
4187 else
4188 {
4189 ptr = ptr3;
4190 c = ((ptr < strEnd) ? (*ptr) : '\0');
4191 }
4192 }
4193 if (number.Kind == NumberBufferKind.FloatingPoint && !number.HasNonZeroTail)
4194 {
4195 int num7 = num3 - number.Scale;
4196 if (num7 > 0)
4197 {
4198 num5 = Math.Min(num5, num7);
4199 number.DigitsCount = num3 - num5;
4200 number.Digits[number.DigitsCount] = 0;
4201 }
4202 }
4203 while (true)
4204 {
4205 if (!IsWhite(c) || (styles & NumberStyles.AllowTrailingWhite) == 0)
4206 {
4207 char* ptr2;
4208 if ((styles & NumberStyles.AllowTrailingSign) != 0 && (num & 1) == 0 && ((ptr2 = MatchChars(ptr, strEnd, info.PositiveSign)) != null || ((ptr2 = MatchNegativeSignChars(ptr, strEnd, info)) != null && (number.IsNegative = true))))
4209 {
4210 num |= 1;
4211 ptr = ptr2 - 1;
4212 }
4213 else if (c == ')' && ((uint)num & 2u) != 0)
4214 {
4215 num &= -3;
4216 }
4217 else
4218 {
4219 if (text == null || (ptr2 = MatchChars(ptr, strEnd, text)) == null)
4220 {
4221 break;
4222 }
4223 text = null;
4224 ptr = ptr2 - 1;
4225 }
4226 }
4227 c = ((++ptr < strEnd) ? (*ptr) : '\0');
4228 }
4229 if ((num & 2) == 0)
4230 {
4231 if ((num & 8) == 0)
4232 {
4233 if (number.Kind != NumberBufferKind.Decimal)
4234 {
4235 number.Scale = 0;
4236 }
4237 if (number.Kind == NumberBufferKind.Integer && (num & 0x10) == 0)
4238 {
4239 number.IsNegative = false;
4240 }
4241 }
4242 str = ptr;
4243 return true;
4244 }
4245 }
4246 str = ptr;
4247 return false;
4248 }
4249
4250 [MethodImpl(MethodImplOptions.AggressiveInlining)]
4252 {
4253 if ((styles & ~NumberStyles.Integer) == 0)
4254 {
4255 return TryParseInt32IntegerStyle(value, styles, info, out result);
4256 }
4257 if ((styles & NumberStyles.AllowHexSpecifier) != 0)
4258 {
4259 result = 0;
4260 return TryParseUInt32HexNumberStyle(value, styles, out Unsafe.As<int, uint>(ref result));
4261 }
4262 return TryParseInt32Number(value, styles, info, out result);
4263 }
4264
4266 {
4267 result = 0;
4268 byte* digits = stackalloc byte[11];
4269 NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits, 11);
4270 if (!TryStringToNumber(value, styles, ref number, info))
4271 {
4272 return ParsingStatus.Failed;
4273 }
4274 if (!TryNumberToInt32(ref number, ref result))
4275 {
4276 return ParsingStatus.Overflow;
4277 }
4278 return ParsingStatus.OK;
4279 }
4280
4282 {
4283 int i;
4284 int num;
4285 if (!value.IsEmpty)
4286 {
4287 i = 0;
4288 num = value[0];
4289 if ((styles & NumberStyles.AllowLeadingWhite) == 0 || !IsWhite(num))
4290 {
4291 goto IL_0048;
4292 }
4293 while (true)
4294 {
4295 i++;
4296 if ((uint)i >= (uint)value.Length)
4297 {
4298 break;
4299 }
4300 num = value[i];
4301 if (IsWhite(num))
4302 {
4303 continue;
4304 }
4305 goto IL_0048;
4306 }
4307 }
4308 goto IL_0289;
4309 IL_027d:
4310 int num2;
4311 int num3;
4312 result = num2 * num3;
4313 return ParsingStatus.OK;
4314 IL_0291:
4315 result = 0;
4316 return ParsingStatus.Overflow;
4317 IL_019f:
4318 if (IsDigit(num))
4319 {
4320 goto IL_01aa;
4321 }
4322 goto IL_0299;
4323 IL_027a:
4324 bool flag;
4325 if (!flag)
4326 {
4327 goto IL_027d;
4328 }
4329 goto IL_0291;
4330 IL_0048:
4331 num3 = 1;
4332 if ((styles & NumberStyles.AllowLeadingSign) != 0)
4333 {
4334 if (info.HasInvariantNumberSigns)
4335 {
4336 if (num == 45)
4337 {
4338 num3 = -1;
4339 i++;
4340 if ((uint)i >= (uint)value.Length)
4341 {
4342 goto IL_0289;
4343 }
4344 num = value[i];
4345 }
4346 else if (num == 43)
4347 {
4348 i++;
4349 if ((uint)i >= (uint)value.Length)
4350 {
4351 goto IL_0289;
4352 }
4353 num = value[i];
4354 }
4355 }
4356 else if (info.AllowHyphenDuringParsing && num == 45)
4357 {
4358 num3 = -1;
4359 i++;
4360 if ((uint)i >= (uint)value.Length)
4361 {
4362 goto IL_0289;
4363 }
4364 num = value[i];
4365 }
4366 else
4367 {
4368 value = value.Slice(i);
4369 i = 0;
4370 string positiveSign = info.PositiveSign;
4371 string negativeSign = info.NegativeSign;
4372 if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign))
4373 {
4374 i += positiveSign.Length;
4375 if ((uint)i >= (uint)value.Length)
4376 {
4377 goto IL_0289;
4378 }
4379 num = value[i];
4380 }
4381 else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign))
4382 {
4383 num3 = -1;
4384 i += negativeSign.Length;
4385 if ((uint)i >= (uint)value.Length)
4386 {
4387 goto IL_0289;
4388 }
4389 num = value[i];
4390 }
4391 }
4392 }
4393 flag = false;
4394 num2 = 0;
4395 if (IsDigit(num))
4396 {
4397 if (num != 48)
4398 {
4399 goto IL_01aa;
4400 }
4401 while (true)
4402 {
4403 i++;
4404 if ((uint)i >= (uint)value.Length)
4405 {
4406 break;
4407 }
4408 num = value[i];
4409 if (num == 48)
4410 {
4411 continue;
4412 }
4413 goto IL_019f;
4414 }
4415 goto IL_027d;
4416 }
4417 goto IL_0289;
4418 IL_01aa:
4419 num2 = num - 48;
4420 i++;
4421 int num4 = 0;
4422 while (num4 < 8)
4423 {
4424 if ((uint)i >= (uint)value.Length)
4425 {
4426 goto IL_027d;
4427 }
4428 num = value[i];
4429 if (IsDigit(num))
4430 {
4431 i++;
4432 num2 = 10 * num2 + num - 48;
4433 num4++;
4434 continue;
4435 }
4436 goto IL_0299;
4437 }
4438 if ((uint)i >= (uint)value.Length)
4439 {
4440 goto IL_027d;
4441 }
4442 num = value[i];
4443 if (IsDigit(num))
4444 {
4445 i++;
4446 flag = num2 > 214748364;
4447 num2 = num2 * 10 + num - 48;
4448 flag = flag || (uint)num2 > (uint)(int.MaxValue + (num3 >>> 31));
4449 if ((uint)i >= (uint)value.Length)
4450 {
4451 goto IL_027a;
4452 }
4453 num = value[i];
4454 while (IsDigit(num))
4455 {
4456 flag = true;
4457 i++;
4458 if ((uint)i < (uint)value.Length)
4459 {
4460 num = value[i];
4461 continue;
4462 }
4463 goto IL_0291;
4464 }
4465 }
4466 goto IL_0299;
4467 IL_0299:
4468 if (IsWhite(num))
4469 {
4470 if ((styles & NumberStyles.AllowTrailingWhite) == 0)
4471 {
4472 goto IL_0289;
4473 }
4474 for (i++; i < value.Length && IsWhite(value[i]); i++)
4475 {
4476 }
4477 if ((uint)i >= (uint)value.Length)
4478 {
4479 goto IL_027a;
4480 }
4481 }
4482 if (TrailingZeros(value, i))
4483 {
4484 goto IL_027a;
4485 }
4486 goto IL_0289;
4487 IL_0289:
4488 result = 0;
4489 return ParsingStatus.Failed;
4490 }
4491
4493 {
4494 int i;
4495 int num;
4496 if (!value.IsEmpty)
4497 {
4498 i = 0;
4499 num = value[0];
4500 if ((styles & NumberStyles.AllowLeadingWhite) == 0 || !IsWhite(num))
4501 {
4502 goto IL_0048;
4503 }
4504 while (true)
4505 {
4506 i++;
4507 if ((uint)i >= (uint)value.Length)
4508 {
4509 break;
4510 }
4511 num = value[i];
4512 if (IsWhite(num))
4513 {
4514 continue;
4515 }
4516 goto IL_0048;
4517 }
4518 }
4519 goto IL_029f;
4520 IL_0292:
4521 long num2;
4522 int num3;
4523 result = num2 * num3;
4524 return ParsingStatus.OK;
4525 IL_02a8:
4526 result = 0L;
4527 return ParsingStatus.Overflow;
4528 IL_01a0:
4529 if (IsDigit(num))
4530 {
4531 goto IL_01ab;
4532 }
4533 goto IL_02b1;
4534 IL_028f:
4535 bool flag;
4536 if (!flag)
4537 {
4538 goto IL_0292;
4539 }
4540 goto IL_02a8;
4541 IL_0048:
4542 num3 = 1;
4543 if ((styles & NumberStyles.AllowLeadingSign) != 0)
4544 {
4545 if (info.HasInvariantNumberSigns)
4546 {
4547 if (num == 45)
4548 {
4549 num3 = -1;
4550 i++;
4551 if ((uint)i >= (uint)value.Length)
4552 {
4553 goto IL_029f;
4554 }
4555 num = value[i];
4556 }
4557 else if (num == 43)
4558 {
4559 i++;
4560 if ((uint)i >= (uint)value.Length)
4561 {
4562 goto IL_029f;
4563 }
4564 num = value[i];
4565 }
4566 }
4567 else if (info.AllowHyphenDuringParsing && num == 45)
4568 {
4569 num3 = -1;
4570 i++;
4571 if ((uint)i >= (uint)value.Length)
4572 {
4573 goto IL_029f;
4574 }
4575 num = value[i];
4576 }
4577 else
4578 {
4579 value = value.Slice(i);
4580 i = 0;
4581 string positiveSign = info.PositiveSign;
4582 string negativeSign = info.NegativeSign;
4583 if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign))
4584 {
4585 i += positiveSign.Length;
4586 if ((uint)i >= (uint)value.Length)
4587 {
4588 goto IL_029f;
4589 }
4590 num = value[i];
4591 }
4592 else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign))
4593 {
4594 num3 = -1;
4595 i += negativeSign.Length;
4596 if ((uint)i >= (uint)value.Length)
4597 {
4598 goto IL_029f;
4599 }
4600 num = value[i];
4601 }
4602 }
4603 }
4604 flag = false;
4605 num2 = 0L;
4606 if (IsDigit(num))
4607 {
4608 if (num != 48)
4609 {
4610 goto IL_01ab;
4611 }
4612 while (true)
4613 {
4614 i++;
4615 if ((uint)i >= (uint)value.Length)
4616 {
4617 break;
4618 }
4619 num = value[i];
4620 if (num == 48)
4621 {
4622 continue;
4623 }
4624 goto IL_01a0;
4625 }
4626 goto IL_0292;
4627 }
4628 goto IL_029f;
4629 IL_01ab:
4630 num2 = num - 48;
4631 i++;
4632 int num4 = 0;
4633 while (num4 < 17)
4634 {
4635 if ((uint)i >= (uint)value.Length)
4636 {
4637 goto IL_0292;
4638 }
4639 num = value[i];
4640 if (IsDigit(num))
4641 {
4642 i++;
4643 num2 = 10 * num2 + num - 48;
4644 num4++;
4645 continue;
4646 }
4647 goto IL_02b1;
4648 }
4649 if ((uint)i >= (uint)value.Length)
4650 {
4651 goto IL_0292;
4652 }
4653 num = value[i];
4654 if (IsDigit(num))
4655 {
4656 i++;
4657 flag = num2 > 922337203685477580L;
4658 num2 = num2 * 10 + num - 48;
4659 flag = flag || (ulong)num2 > (ulong)(long.MaxValue + (long)(uint)(num3 >>> 31));
4660 if ((uint)i >= (uint)value.Length)
4661 {
4662 goto IL_028f;
4663 }
4664 num = value[i];
4665 while (IsDigit(num))
4666 {
4667 flag = true;
4668 i++;
4669 if ((uint)i < (uint)value.Length)
4670 {
4671 num = value[i];
4672 continue;
4673 }
4674 goto IL_02a8;
4675 }
4676 }
4677 goto IL_02b1;
4678 IL_02b1:
4679 if (IsWhite(num))
4680 {
4681 if ((styles & NumberStyles.AllowTrailingWhite) == 0)
4682 {
4683 goto IL_029f;
4684 }
4685 for (i++; i < value.Length && IsWhite(value[i]); i++)
4686 {
4687 }
4688 if ((uint)i >= (uint)value.Length)
4689 {
4690 goto IL_028f;
4691 }
4692 }
4693 if (TrailingZeros(value, i))
4694 {
4695 goto IL_028f;
4696 }
4697 goto IL_029f;
4698 IL_029f:
4699 result = 0L;
4700 return ParsingStatus.Failed;
4701 }
4702
4703 [MethodImpl(MethodImplOptions.AggressiveInlining)]
4705 {
4706 if ((styles & ~NumberStyles.Integer) == 0)
4707 {
4708 return TryParseInt64IntegerStyle(value, styles, info, out result);
4709 }
4710 if ((styles & NumberStyles.AllowHexSpecifier) != 0)
4711 {
4712 result = 0L;
4713 return TryParseUInt64HexNumberStyle(value, styles, out Unsafe.As<long, ulong>(ref result));
4714 }
4715 return TryParseInt64Number(value, styles, info, out result);
4716 }
4717
4719 {
4720 result = 0L;
4721 byte* digits = stackalloc byte[20];
4722 NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits, 20);
4723 if (!TryStringToNumber(value, styles, ref number, info))
4724 {
4725 return ParsingStatus.Failed;
4726 }
4727 if (!TryNumberToInt64(ref number, ref result))
4728 {
4729 return ParsingStatus.Overflow;
4730 }
4731 return ParsingStatus.OK;
4732 }
4733
4734 [MethodImpl(MethodImplOptions.AggressiveInlining)]
4736 {
4737 if ((styles & ~NumberStyles.Integer) == 0)
4738 {
4739 return TryParseUInt32IntegerStyle(value, styles, info, out result);
4740 }
4741 if ((styles & NumberStyles.AllowHexSpecifier) != 0)
4742 {
4743 return TryParseUInt32HexNumberStyle(value, styles, out result);
4744 }
4745 return TryParseUInt32Number(value, styles, info, out result);
4746 }
4747
4749 {
4750 result = 0u;
4751 byte* digits = stackalloc byte[11];
4752 NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits, 11);
4753 if (!TryStringToNumber(value, styles, ref number, info))
4754 {
4755 return ParsingStatus.Failed;
4756 }
4757 if (!TryNumberToUInt32(ref number, ref result))
4758 {
4759 return ParsingStatus.Overflow;
4760 }
4761 return ParsingStatus.OK;
4762 }
4763
4765 {
4766 int i;
4767 int num;
4768 if (!value.IsEmpty)
4769 {
4770 i = 0;
4771 num = value[0];
4772 if ((styles & NumberStyles.AllowLeadingWhite) == 0 || !IsWhite(num))
4773 {
4774 goto IL_0048;
4775 }
4776 while (true)
4777 {
4778 i++;
4779 if ((uint)i >= (uint)value.Length)
4780 {
4781 break;
4782 }
4783 num = value[i];
4784 if (IsWhite(num))
4785 {
4786 continue;
4787 }
4788 goto IL_0048;
4789 }
4790 }
4791 goto IL_0281;
4792 IL_01a7:
4793 int num2 = num - 48;
4794 i++;
4795 int num3 = 0;
4796 while (num3 < 8)
4797 {
4798 if ((uint)i >= (uint)value.Length)
4799 {
4800 goto IL_0275;
4801 }
4802 num = value[i];
4803 if (IsDigit(num))
4804 {
4805 i++;
4806 num2 = 10 * num2 + num - 48;
4807 num3++;
4808 continue;
4809 }
4810 goto IL_0293;
4811 }
4812 if ((uint)i >= (uint)value.Length)
4813 {
4814 goto IL_0275;
4815 }
4816 num = value[i];
4817 bool flag;
4818 if (IsDigit(num))
4819 {
4820 i++;
4821 flag = flag || (uint)num2 > 429496729u || (num2 == 429496729 && num > 53);
4822 num2 = num2 * 10 + num - 48;
4823 if ((uint)i >= (uint)value.Length)
4824 {
4825 goto IL_0275;
4826 }
4827 num = value[i];
4828 while (IsDigit(num))
4829 {
4830 flag = true;
4831 i++;
4832 if ((uint)i < (uint)value.Length)
4833 {
4834 num = value[i];
4835 continue;
4836 }
4837 goto IL_0289;
4838 }
4839 }
4840 goto IL_0293;
4841 IL_0278:
4842 result = (uint)num2;
4843 return ParsingStatus.OK;
4844 IL_019c:
4845 if (IsDigit(num))
4846 {
4847 goto IL_01a7;
4848 }
4849 flag = false;
4850 goto IL_0293;
4851 IL_0275:
4852 if (!flag)
4853 {
4854 goto IL_0278;
4855 }
4856 goto IL_0289;
4857 IL_0048:
4858 flag = false;
4859 if ((styles & NumberStyles.AllowLeadingSign) != 0)
4860 {
4861 if (info.HasInvariantNumberSigns)
4862 {
4863 if (num == 43)
4864 {
4865 i++;
4866 if ((uint)i >= (uint)value.Length)
4867 {
4868 goto IL_0281;
4869 }
4870 num = value[i];
4871 }
4872 else if (num == 45)
4873 {
4874 flag = true;
4875 i++;
4876 if ((uint)i >= (uint)value.Length)
4877 {
4878 goto IL_0281;
4879 }
4880 num = value[i];
4881 }
4882 }
4883 else if (info.AllowHyphenDuringParsing && num == 45)
4884 {
4885 flag = true;
4886 i++;
4887 if ((uint)i >= (uint)value.Length)
4888 {
4889 goto IL_0281;
4890 }
4891 num = value[i];
4892 }
4893 else
4894 {
4895 value = value.Slice(i);
4896 i = 0;
4897 string positiveSign = info.PositiveSign;
4898 string negativeSign = info.NegativeSign;
4899 if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign))
4900 {
4901 i += positiveSign.Length;
4902 if ((uint)i >= (uint)value.Length)
4903 {
4904 goto IL_0281;
4905 }
4906 num = value[i];
4907 }
4908 else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign))
4909 {
4910 flag = true;
4911 i += negativeSign.Length;
4912 if ((uint)i >= (uint)value.Length)
4913 {
4914 goto IL_0281;
4915 }
4916 num = value[i];
4917 }
4918 }
4919 }
4920 num2 = 0;
4921 if (IsDigit(num))
4922 {
4923 if (num != 48)
4924 {
4925 goto IL_01a7;
4926 }
4927 while (true)
4928 {
4929 i++;
4930 if ((uint)i >= (uint)value.Length)
4931 {
4932 break;
4933 }
4934 num = value[i];
4935 if (num == 48)
4936 {
4937 continue;
4938 }
4939 goto IL_019c;
4940 }
4941 goto IL_0278;
4942 }
4943 goto IL_0281;
4944 IL_0293:
4945 if (IsWhite(num))
4946 {
4947 if ((styles & NumberStyles.AllowTrailingWhite) == 0)
4948 {
4949 goto IL_0281;
4950 }
4951 for (i++; i < value.Length && IsWhite(value[i]); i++)
4952 {
4953 }
4954 if ((uint)i >= (uint)value.Length)
4955 {
4956 goto IL_0275;
4957 }
4958 }
4959 if (TrailingZeros(value, i))
4960 {
4961 goto IL_0275;
4962 }
4963 goto IL_0281;
4964 IL_0289:
4965 result = 0u;
4966 return ParsingStatus.Overflow;
4967 IL_0281:
4968 result = 0u;
4969 return ParsingStatus.Failed;
4970 }
4971
4973 {
4974 int i;
4975 int num;
4976 if (!value.IsEmpty)
4977 {
4978 i = 0;
4979 num = value[0];
4980 if ((styles & NumberStyles.AllowLeadingWhite) == 0 || !IsWhite(num))
4981 {
4982 goto IL_0048;
4983 }
4984 while (true)
4985 {
4986 i++;
4987 if ((uint)i >= (uint)value.Length)
4988 {
4989 break;
4990 }
4991 num = value[i];
4992 if (IsWhite(num))
4993 {
4994 continue;
4995 }
4996 goto IL_0048;
4997 }
4998 }
4999 goto IL_011f;
5000 IL_0087:
5001 uint num2 = (uint)HexConverter.FromChar(num);
5002 i++;
5003 int num3 = 0;
5004 while (num3 < 7)
5005 {
5006 if ((uint)i >= (uint)value.Length)
5007 {
5008 goto IL_0116;
5009 }
5010 num = value[i];
5011 uint num4 = (uint)HexConverter.FromChar(num);
5012 if (num4 != 255)
5013 {
5014 i++;
5015 num2 = 16 * num2 + num4;
5016 num3++;
5017 continue;
5018 }
5019 goto IL_012f;
5020 }
5021 if ((uint)i >= (uint)value.Length)
5022 {
5023 goto IL_0116;
5024 }
5025 num = value[i];
5026 if (HexConverter.IsHexChar(num))
5027 {
5028 while (true)
5029 {
5030 i++;
5031 if ((uint)i >= (uint)value.Length)
5032 {
5033 break;
5034 }
5035 num = value[i];
5036 if (HexConverter.IsHexChar(num))
5037 {
5038 continue;
5039 }
5040 goto IL_010f;
5041 }
5042 goto IL_0127;
5043 }
5044 goto IL_012f;
5045 IL_0127:
5046 result = 0u;
5047 return ParsingStatus.Overflow;
5048 IL_0113:
5049 bool flag;
5050 if (!flag)
5051 {
5052 goto IL_0116;
5053 }
5054 goto IL_0127;
5055 IL_011f:
5056 result = 0u;
5057 return ParsingStatus.Failed;
5058 IL_0048:
5059 flag = false;
5060 num2 = 0u;
5061 if (HexConverter.IsHexChar(num))
5062 {
5063 if (num != 48)
5064 {
5065 goto IL_0087;
5066 }
5067 while (true)
5068 {
5069 i++;
5070 if ((uint)i >= (uint)value.Length)
5071 {
5072 break;
5073 }
5074 num = value[i];
5075 if (num == 48)
5076 {
5077 continue;
5078 }
5079 goto IL_007c;
5080 }
5081 goto IL_0116;
5082 }
5083 goto IL_011f;
5084 IL_010f:
5085 flag = true;
5086 goto IL_012f;
5087 IL_012f:
5088 if (IsWhite(num))
5089 {
5090 if ((styles & NumberStyles.AllowTrailingWhite) == 0)
5091 {
5092 goto IL_011f;
5093 }
5094 for (i++; i < value.Length && IsWhite(value[i]); i++)
5095 {
5096 }
5097 if ((uint)i >= (uint)value.Length)
5098 {
5099 goto IL_0113;
5100 }
5101 }
5102 if (TrailingZeros(value, i))
5103 {
5104 goto IL_0113;
5105 }
5106 goto IL_011f;
5107 IL_0116:
5108 result = num2;
5109 return ParsingStatus.OK;
5110 IL_007c:
5111 if (HexConverter.IsHexChar(num))
5112 {
5113 goto IL_0087;
5114 }
5115 goto IL_012f;
5116 }
5117
5118 [MethodImpl(MethodImplOptions.AggressiveInlining)]
5120 {
5121 if ((styles & ~NumberStyles.Integer) == 0)
5122 {
5123 return TryParseUInt64IntegerStyle(value, styles, info, out result);
5124 }
5125 if ((styles & NumberStyles.AllowHexSpecifier) != 0)
5126 {
5127 return TryParseUInt64HexNumberStyle(value, styles, out result);
5128 }
5129 return TryParseUInt64Number(value, styles, info, out result);
5130 }
5131
5133 {
5134 result = 0uL;
5135 byte* digits = stackalloc byte[21];
5136 NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits, 21);
5137 if (!TryStringToNumber(value, styles, ref number, info))
5138 {
5139 return ParsingStatus.Failed;
5140 }
5141 if (!TryNumberToUInt64(ref number, ref result))
5142 {
5143 return ParsingStatus.Overflow;
5144 }
5145 return ParsingStatus.OK;
5146 }
5147
5149 {
5150 int i;
5151 int num;
5152 if (!value.IsEmpty)
5153 {
5154 i = 0;
5155 num = value[0];
5156 if ((styles & NumberStyles.AllowLeadingWhite) == 0 || !IsWhite(num))
5157 {
5158 goto IL_0048;
5159 }
5160 while (true)
5161 {
5162 i++;
5163 if ((uint)i >= (uint)value.Length)
5164 {
5165 break;
5166 }
5167 num = value[i];
5168 if (IsWhite(num))
5169 {
5170 continue;
5171 }
5172 goto IL_0048;
5173 }
5174 }
5175 goto IL_0295;
5176 IL_01a8:
5177 long num2 = num - 48;
5178 i++;
5179 int num3 = 0;
5180 while (num3 < 18)
5181 {
5182 if ((uint)i >= (uint)value.Length)
5183 {
5184 goto IL_0289;
5185 }
5186 num = value[i];
5187 if (IsDigit(num))
5188 {
5189 i++;
5190 num2 = 10 * num2 + num - 48;
5191 num3++;
5192 continue;
5193 }
5194 goto IL_02a9;
5195 }
5196 if ((uint)i >= (uint)value.Length)
5197 {
5198 goto IL_0289;
5199 }
5200 num = value[i];
5201 bool flag;
5202 if (IsDigit(num))
5203 {
5204 i++;
5205 flag = flag || (ulong)num2 > 1844674407370955161uL || (num2 == 1844674407370955161L && num > 53);
5206 num2 = num2 * 10 + num - 48;
5207 if ((uint)i >= (uint)value.Length)
5208 {
5209 goto IL_0289;
5210 }
5211 num = value[i];
5212 while (IsDigit(num))
5213 {
5214 flag = true;
5215 i++;
5216 if ((uint)i < (uint)value.Length)
5217 {
5218 num = value[i];
5219 continue;
5220 }
5221 goto IL_029e;
5222 }
5223 }
5224 goto IL_02a9;
5225 IL_028c:
5226 result = (ulong)num2;
5227 return ParsingStatus.OK;
5228 IL_019d:
5229 if (IsDigit(num))
5230 {
5231 goto IL_01a8;
5232 }
5233 flag = false;
5234 goto IL_02a9;
5235 IL_0289:
5236 if (!flag)
5237 {
5238 goto IL_028c;
5239 }
5240 goto IL_029e;
5241 IL_0048:
5242 flag = false;
5243 if ((styles & NumberStyles.AllowLeadingSign) != 0)
5244 {
5245 if (info.HasInvariantNumberSigns)
5246 {
5247 if (num == 43)
5248 {
5249 i++;
5250 if ((uint)i >= (uint)value.Length)
5251 {
5252 goto IL_0295;
5253 }
5254 num = value[i];
5255 }
5256 else if (num == 45)
5257 {
5258 flag = true;
5259 i++;
5260 if ((uint)i >= (uint)value.Length)
5261 {
5262 goto IL_0295;
5263 }
5264 num = value[i];
5265 }
5266 }
5267 else if (info.AllowHyphenDuringParsing && num == 45)
5268 {
5269 flag = true;
5270 i++;
5271 if ((uint)i >= (uint)value.Length)
5272 {
5273 goto IL_0295;
5274 }
5275 num = value[i];
5276 }
5277 else
5278 {
5279 value = value.Slice(i);
5280 i = 0;
5281 string positiveSign = info.PositiveSign;
5282 string negativeSign = info.NegativeSign;
5283 if (!string.IsNullOrEmpty(positiveSign) && value.StartsWith(positiveSign))
5284 {
5285 i += positiveSign.Length;
5286 if ((uint)i >= (uint)value.Length)
5287 {
5288 goto IL_0295;
5289 }
5290 num = value[i];
5291 }
5292 else if (!string.IsNullOrEmpty(negativeSign) && value.StartsWith(negativeSign))
5293 {
5294 flag = true;
5295 i += negativeSign.Length;
5296 if ((uint)i >= (uint)value.Length)
5297 {
5298 goto IL_0295;
5299 }
5300 num = value[i];
5301 }
5302 }
5303 }
5304 num2 = 0L;
5305 if (IsDigit(num))
5306 {
5307 if (num != 48)
5308 {
5309 goto IL_01a8;
5310 }
5311 while (true)
5312 {
5313 i++;
5314 if ((uint)i >= (uint)value.Length)
5315 {
5316 break;
5317 }
5318 num = value[i];
5319 if (num == 48)
5320 {
5321 continue;
5322 }
5323 goto IL_019d;
5324 }
5325 goto IL_028c;
5326 }
5327 goto IL_0295;
5328 IL_02a9:
5329 if (IsWhite(num))
5330 {
5331 if ((styles & NumberStyles.AllowTrailingWhite) == 0)
5332 {
5333 goto IL_0295;
5334 }
5335 for (i++; i < value.Length && IsWhite(value[i]); i++)
5336 {
5337 }
5338 if ((uint)i >= (uint)value.Length)
5339 {
5340 goto IL_0289;
5341 }
5342 }
5343 if (TrailingZeros(value, i))
5344 {
5345 goto IL_0289;
5346 }
5347 goto IL_0295;
5348 IL_029e:
5349 result = 0uL;
5350 return ParsingStatus.Overflow;
5351 IL_0295:
5352 result = 0uL;
5353 return ParsingStatus.Failed;
5354 }
5355
5357 {
5358 int i;
5359 int num;
5360 if (!value.IsEmpty)
5361 {
5362 i = 0;
5363 num = value[0];
5364 if ((styles & NumberStyles.AllowLeadingWhite) == 0 || !IsWhite(num))
5365 {
5366 goto IL_0048;
5367 }
5368 while (true)
5369 {
5370 i++;
5371 if ((uint)i >= (uint)value.Length)
5372 {
5373 break;
5374 }
5375 num = value[i];
5376 if (IsWhite(num))
5377 {
5378 continue;
5379 }
5380 goto IL_0048;
5381 }
5382 }
5383 goto IL_0124;
5384 IL_0088:
5385 ulong num2 = (uint)HexConverter.FromChar(num);
5386 i++;
5387 int num3 = 0;
5388 while (num3 < 15)
5389 {
5390 if ((uint)i >= (uint)value.Length)
5391 {
5392 goto IL_011b;
5393 }
5394 num = value[i];
5395 uint num4 = (uint)HexConverter.FromChar(num);
5396 if (num4 != 255)
5397 {
5398 i++;
5399 num2 = 16 * num2 + num4;
5400 num3++;
5401 continue;
5402 }
5403 goto IL_0136;
5404 }
5405 if ((uint)i >= (uint)value.Length)
5406 {
5407 goto IL_011b;
5408 }
5409 num = value[i];
5410 if (HexConverter.IsHexChar(num))
5411 {
5412 while (true)
5413 {
5414 i++;
5415 if ((uint)i >= (uint)value.Length)
5416 {
5417 break;
5418 }
5419 num = value[i];
5420 if (HexConverter.IsHexChar(num))
5421 {
5422 continue;
5423 }
5424 goto IL_0114;
5425 }
5426 goto IL_012d;
5427 }
5428 goto IL_0136;
5429 IL_012d:
5430 result = 0uL;
5431 return ParsingStatus.Overflow;
5432 IL_0118:
5433 bool flag;
5434 if (!flag)
5435 {
5436 goto IL_011b;
5437 }
5438 goto IL_012d;
5439 IL_0124:
5440 result = 0uL;
5441 return ParsingStatus.Failed;
5442 IL_0048:
5443 flag = false;
5444 num2 = 0uL;
5445 if (HexConverter.IsHexChar(num))
5446 {
5447 if (num != 48)
5448 {
5449 goto IL_0088;
5450 }
5451 while (true)
5452 {
5453 i++;
5454 if ((uint)i >= (uint)value.Length)
5455 {
5456 break;
5457 }
5458 num = value[i];
5459 if (num == 48)
5460 {
5461 continue;
5462 }
5463 goto IL_007d;
5464 }
5465 goto IL_011b;
5466 }
5467 goto IL_0124;
5468 IL_0114:
5469 flag = true;
5470 goto IL_0136;
5471 IL_0136:
5472 if (IsWhite(num))
5473 {
5474 if ((styles & NumberStyles.AllowTrailingWhite) == 0)
5475 {
5476 goto IL_0124;
5477 }
5478 for (i++; i < value.Length && IsWhite(value[i]); i++)
5479 {
5480 }
5481 if ((uint)i >= (uint)value.Length)
5482 {
5483 goto IL_0118;
5484 }
5485 }
5486 if (TrailingZeros(value, i))
5487 {
5488 goto IL_0118;
5489 }
5490 goto IL_0124;
5491 IL_011b:
5492 result = num2;
5493 return ParsingStatus.OK;
5494 IL_007d:
5495 if (HexConverter.IsHexChar(num))
5496 {
5497 goto IL_0088;
5498 }
5499 goto IL_0136;
5500 }
5501
5503 {
5504 decimal result;
5505 ParsingStatus parsingStatus = TryParseDecimal(value, styles, info, out result);
5506 if (parsingStatus != 0)
5507 {
5508 ThrowOverflowOrFormatException(parsingStatus, TypeCode.Decimal);
5509 }
5510 return result;
5511 }
5512
5513 internal unsafe static bool TryNumberToDecimal(ref NumberBuffer number, ref decimal value)
5514 {
5515 byte* ptr = number.GetDigitsPointer();
5516 int num = number.Scale;
5517 bool isNegative = number.IsNegative;
5518 uint num2 = *ptr;
5519 if (num2 == 0)
5520 {
5521 value = new decimal(0, 0, 0, isNegative, (byte)Math.Clamp(-num, 0, 28));
5522 return true;
5523 }
5524 if (num > 29)
5525 {
5526 return false;
5527 }
5528 ulong num3 = 0uL;
5529 while (num > -28)
5530 {
5531 num--;
5532 num3 *= 10;
5533 num3 += num2 - 48;
5534 num2 = *(++ptr);
5535 if (num3 >= 1844674407370955161L)
5536 {
5537 break;
5538 }
5539 if (num2 != 0)
5540 {
5541 continue;
5542 }
5543 while (num > 0)
5544 {
5545 num--;
5546 num3 *= 10;
5547 if (num3 >= 1844674407370955161L)
5548 {
5549 break;
5550 }
5551 }
5552 break;
5553 }
5554 uint num4 = 0u;
5555 while ((num > 0 || (num2 != 0 && num > -28)) && (num4 < 429496729 || (num4 == 429496729 && (num3 < 11068046444225730969uL || (num3 == 11068046444225730969uL && num2 <= 53)))))
5556 {
5557 ulong num5 = (ulong)(uint)num3 * 10uL;
5558 ulong num6 = (ulong)((long)(uint)(num3 >> 32) * 10L) + (num5 >> 32);
5559 num3 = (uint)num5 + (num6 << 32);
5560 num4 = (uint)(int)(num6 >> 32) + num4 * 10;
5561 if (num2 != 0)
5562 {
5563 num2 -= 48;
5564 num3 += num2;
5565 if (num3 < num2)
5566 {
5567 num4++;
5568 }
5569 num2 = *(++ptr);
5570 }
5571 num--;
5572 }
5573 if (num2 >= 53)
5574 {
5575 if (num2 == 53 && (num3 & 1) == 0L)
5576 {
5577 num2 = *(++ptr);
5578 bool flag = !number.HasNonZeroTail;
5579 while (num2 != 0 && flag)
5580 {
5581 flag = flag && num2 == 48;
5582 num2 = *(++ptr);
5583 }
5584 if (flag)
5585 {
5586 goto IL_01a8;
5587 }
5588 }
5589 if (++num3 == 0L && ++num4 == 0)
5590 {
5591 num3 = 11068046444225730970uL;
5592 num4 = 429496729u;
5593 num++;
5594 }
5595 }
5596 goto IL_01a8;
5597 IL_01a8:
5598 if (num > 0)
5599 {
5600 return false;
5601 }
5602 if (num <= -29)
5603 {
5604 value = new decimal(0, 0, 0, isNegative, 28);
5605 }
5606 else
5607 {
5608 value = new decimal((int)num3, (int)(num3 >> 32), (int)num4, isNegative, (byte)(-num));
5609 }
5610 return true;
5611 }
5612
5614 {
5615 if (!TryParseDouble(value, styles, info, out var result))
5616 {
5618 }
5619 return result;
5620 }
5621
5623 {
5624 if (!TryParseSingle(value, styles, info, out var result))
5625 {
5627 }
5628 return result;
5629 }
5630
5632 {
5633 if (!TryParseHalf(value, styles, info, out var result))
5634 {
5636 }
5637 return result;
5638 }
5639
5640 internal unsafe static ParsingStatus TryParseDecimal(ReadOnlySpan<char> value, NumberStyles styles, NumberFormatInfo info, out decimal result)
5641 {
5642 byte* digits = stackalloc byte[31];
5643 NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, digits, 31);
5644 result = default(decimal);
5645 if (!TryStringToNumber(value, styles, ref number, info))
5646 {
5647 return ParsingStatus.Failed;
5648 }
5649 if (!TryNumberToDecimal(ref number, ref result))
5650 {
5651 return ParsingStatus.Overflow;
5652 }
5653 return ParsingStatus.OK;
5654 }
5655
5656 internal static bool SpanStartsWith(ReadOnlySpan<char> span, char c)
5657 {
5658 if (!span.IsEmpty)
5659 {
5660 return span[0] == c;
5661 }
5662 return false;
5663 }
5664
5665 internal unsafe static bool TryParseDouble(ReadOnlySpan<char> value, NumberStyles styles, NumberFormatInfo info, out double result)
5666 {
5667 byte* digits = stackalloc byte[769];
5668 NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, digits, 769);
5669 if (!TryStringToNumber(value, styles, ref number, info))
5670 {
5671 ReadOnlySpan<char> span = value.Trim();
5672 if (span.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol))
5673 {
5674 result = double.PositiveInfinity;
5675 }
5676 else if (span.EqualsOrdinalIgnoreCase(info.NegativeInfinitySymbol))
5677 {
5678 result = double.NegativeInfinity;
5679 }
5680 else if (span.EqualsOrdinalIgnoreCase(info.NaNSymbol))
5681 {
5682 result = double.NaN;
5683 }
5684 else if (span.StartsWith(info.PositiveSign, StringComparison.OrdinalIgnoreCase))
5685 {
5686 span = span.Slice(info.PositiveSign.Length);
5687 if (span.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol))
5688 {
5689 result = double.PositiveInfinity;
5690 }
5691 else
5692 {
5693 if (!span.EqualsOrdinalIgnoreCase(info.NaNSymbol))
5694 {
5695 result = 0.0;
5696 return false;
5697 }
5698 result = double.NaN;
5699 }
5700 }
5701 else
5702 {
5703 if ((!span.StartsWith(info.NegativeSign, StringComparison.OrdinalIgnoreCase) || !span.Slice(info.NegativeSign.Length).EqualsOrdinalIgnoreCase(info.NaNSymbol)) && (!info.AllowHyphenDuringParsing || !SpanStartsWith(span, '-') || !span.Slice(1).EqualsOrdinalIgnoreCase(info.NaNSymbol)))
5704 {
5705 result = 0.0;
5706 return false;
5707 }
5708 result = double.NaN;
5709 }
5710 }
5711 else
5712 {
5713 result = NumberToDouble(ref number);
5714 }
5715 return true;
5716 }
5717
5718 internal unsafe static bool TryParseHalf(ReadOnlySpan<char> value, NumberStyles styles, NumberFormatInfo info, out Half result)
5719 {
5720 byte* digits = stackalloc byte[21];
5721 NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, digits, 21);
5722 if (!TryStringToNumber(value, styles, ref number, info))
5723 {
5724 ReadOnlySpan<char> span = value.Trim();
5725 if (span.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol))
5726 {
5727 result = Half.PositiveInfinity;
5728 }
5729 else if (span.EqualsOrdinalIgnoreCase(info.NegativeInfinitySymbol))
5730 {
5731 result = Half.NegativeInfinity;
5732 }
5733 else if (span.EqualsOrdinalIgnoreCase(info.NaNSymbol))
5734 {
5735 result = Half.NaN;
5736 }
5737 else if (span.StartsWith(info.PositiveSign, StringComparison.OrdinalIgnoreCase))
5738 {
5739 span = span.Slice(info.PositiveSign.Length);
5740 if (!info.PositiveInfinitySymbol.StartsWith(info.PositiveSign, StringComparison.OrdinalIgnoreCase) && span.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol))
5741 {
5742 result = Half.PositiveInfinity;
5743 }
5744 else
5745 {
5746 if (info.NaNSymbol.StartsWith(info.PositiveSign, StringComparison.OrdinalIgnoreCase) || !span.EqualsOrdinalIgnoreCase(info.NaNSymbol))
5747 {
5748 result = (Half)0f;
5749 return false;
5750 }
5751 result = Half.NaN;
5752 }
5753 }
5754 else if (span.StartsWith(info.NegativeSign, StringComparison.OrdinalIgnoreCase) && !info.NaNSymbol.StartsWith(info.NegativeSign, StringComparison.OrdinalIgnoreCase) && span.Slice(info.NegativeSign.Length).EqualsOrdinalIgnoreCase(info.NaNSymbol))
5755 {
5756 result = Half.NaN;
5757 }
5758 else
5759 {
5760 if (!info.AllowHyphenDuringParsing || !SpanStartsWith(span, '-') || info.NaNSymbol.StartsWith(info.NegativeSign, StringComparison.OrdinalIgnoreCase) || info.NaNSymbol.StartsWith('-') || !span.Slice(1).EqualsOrdinalIgnoreCase(info.NaNSymbol))
5761 {
5762 result = (Half)0f;
5763 return false;
5764 }
5765 result = Half.NaN;
5766 }
5767 }
5768 else
5769 {
5770 result = NumberToHalf(ref number);
5771 }
5772 return true;
5773 }
5774
5775 internal unsafe static bool TryParseSingle(ReadOnlySpan<char> value, NumberStyles styles, NumberFormatInfo info, out float result)
5776 {
5777 byte* digits = stackalloc byte[114];
5778 NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, digits, 114);
5779 if (!TryStringToNumber(value, styles, ref number, info))
5780 {
5781 ReadOnlySpan<char> span = value.Trim();
5782 if (span.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol))
5783 {
5784 result = float.PositiveInfinity;
5785 }
5786 else if (span.EqualsOrdinalIgnoreCase(info.NegativeInfinitySymbol))
5787 {
5788 result = float.NegativeInfinity;
5789 }
5790 else if (span.EqualsOrdinalIgnoreCase(info.NaNSymbol))
5791 {
5792 result = float.NaN;
5793 }
5794 else if (span.StartsWith(info.PositiveSign, StringComparison.OrdinalIgnoreCase))
5795 {
5796 span = span.Slice(info.PositiveSign.Length);
5797 if (!info.PositiveInfinitySymbol.StartsWith(info.PositiveSign, StringComparison.OrdinalIgnoreCase) && span.EqualsOrdinalIgnoreCase(info.PositiveInfinitySymbol))
5798 {
5799 result = float.PositiveInfinity;
5800 }
5801 else
5802 {
5803 if (info.NaNSymbol.StartsWith(info.PositiveSign, StringComparison.OrdinalIgnoreCase) || !span.EqualsOrdinalIgnoreCase(info.NaNSymbol))
5804 {
5805 result = 0f;
5806 return false;
5807 }
5808 result = float.NaN;
5809 }
5810 }
5811 else if (span.StartsWith(info.NegativeSign, StringComparison.OrdinalIgnoreCase) && !info.NaNSymbol.StartsWith(info.NegativeSign, StringComparison.OrdinalIgnoreCase) && span.Slice(info.NegativeSign.Length).EqualsOrdinalIgnoreCase(info.NaNSymbol))
5812 {
5813 result = float.NaN;
5814 }
5815 else
5816 {
5817 if (!info.AllowHyphenDuringParsing || !SpanStartsWith(span, '-') || info.NaNSymbol.StartsWith(info.NegativeSign, StringComparison.OrdinalIgnoreCase) || info.NaNSymbol.StartsWith('-') || !span.Slice(1).EqualsOrdinalIgnoreCase(info.NaNSymbol))
5818 {
5819 result = 0f;
5820 return false;
5821 }
5822 result = float.NaN;
5823 }
5824 }
5825 else
5826 {
5827 result = NumberToSingle(ref number);
5828 }
5829 return true;
5830 }
5831
5833 {
5834 fixed (char* ptr = &MemoryMarshal.GetReference(value))
5835 {
5836 char* str = ptr;
5837 if (!TryParseNumber(ref str, str + value.Length, styles, ref number, info) || ((int)(str - ptr) < value.Length && !TrailingZeros(value, (int)(str - ptr))))
5838 {
5839 return false;
5840 }
5841 }
5842 return true;
5843 }
5844
5846 {
5847 for (int i = index; (uint)i < (uint)value.Length; i++)
5848 {
5849 if (value[i] != 0)
5850 {
5851 return false;
5852 }
5853 }
5854 return true;
5855 }
5856
5857 private static bool IsSpaceReplacingChar(char c)
5858 {
5859 if (c != '\u00a0')
5860 {
5861 return c == '\u202f';
5862 }
5863 return true;
5864 }
5865
5866 [MethodImpl(MethodImplOptions.AggressiveInlining)]
5867 private unsafe static char* MatchNegativeSignChars(char* p, char* pEnd, NumberFormatInfo info)
5868 {
5869 char* ptr = MatchChars(p, pEnd, info.NegativeSign);
5870 if (ptr == null && info.AllowHyphenDuringParsing && p < pEnd && *p == '-')
5871 {
5872 ptr = p + 1;
5873 }
5874 return ptr;
5875 }
5876
5877 private unsafe static char* MatchChars(char* p, char* pEnd, string value)
5878 {
5879 fixed (char* ptr = value)
5880 {
5881 char* ptr2 = ptr;
5882 if (*ptr2 != 0)
5883 {
5884 while (true)
5885 {
5886 char c = ((p < pEnd) ? (*p) : '\0');
5887 if (c != *ptr2 && (!IsSpaceReplacingChar(*ptr2) || c != ' '))
5888 {
5889 break;
5890 }
5891 p++;
5892 ptr2++;
5893 if (*ptr2 == '\0')
5894 {
5895 return p;
5896 }
5897 }
5898 }
5899 }
5900 return null;
5901 }
5902
5903 private static bool IsWhite(int ch)
5904 {
5905 if (ch != 32 && (uint)(ch - 9) > 4u)
5906 {
5907 return false;
5908 }
5909 return true;
5910 }
5911
5912 private static bool IsDigit(int ch)
5913 {
5914 return (uint)(ch - 48) <= 9u;
5915 }
5916
5917 [DoesNotReturn]
5919 {
5920 throw GetException(status, type);
5921 }
5922
5923 [DoesNotReturn]
5925 {
5926 throw GetException(ParsingStatus.Overflow, type);
5927 }
5928
5930 {
5931 if (status == ParsingStatus.Failed)
5932 {
5934 }
5935 return new OverflowException(type switch
5936 {
5937 TypeCode.SByte => SR.Overflow_SByte,
5938 TypeCode.Byte => SR.Overflow_Byte,
5939 TypeCode.Int16 => SR.Overflow_Int16,
5940 TypeCode.UInt16 => SR.Overflow_UInt16,
5941 TypeCode.Int32 => SR.Overflow_Int32,
5942 TypeCode.UInt32 => SR.Overflow_UInt32,
5943 TypeCode.Int64 => SR.Overflow_Int64,
5944 TypeCode.UInt64 => SR.Overflow_UInt64,
5945 _ => SR.Overflow_Decimal,
5946 });
5947 }
5948
5949 internal static double NumberToDouble(ref NumberBuffer number)
5950 {
5951 double num;
5952 if (number.DigitsCount == 0 || number.Scale < -324)
5953 {
5954 num = 0.0;
5955 }
5956 else if (number.Scale > 309)
5957 {
5958 num = double.PositiveInfinity;
5959 }
5960 else
5961 {
5964 }
5965 if (!number.IsNegative)
5966 {
5967 return num;
5968 }
5969 return 0.0 - num;
5970 }
5971
5972 internal static Half NumberToHalf(ref NumberBuffer number)
5973 {
5974 Half half;
5975 if (number.DigitsCount == 0 || number.Scale < -8)
5976 {
5977 half = default(Half);
5978 }
5979 else if (number.Scale > 5)
5980 {
5981 half = Half.PositiveInfinity;
5982 }
5983 else
5984 {
5986 half = new Half(value);
5987 }
5988 if (!number.IsNegative)
5989 {
5990 return half;
5991 }
5992 return Half.Negate(half);
5993 }
5994
5995 internal static float NumberToSingle(ref NumberBuffer number)
5996 {
5997 float num;
5998 if (number.DigitsCount == 0 || number.Scale < -45)
5999 {
6000 num = 0f;
6001 }
6002 else if (number.Scale > 39)
6003 {
6004 num = float.PositiveInfinity;
6005 }
6006 else
6007 {
6010 }
6011 if (!number.IsNegative)
6012 {
6013 return num;
6014 }
6015 return 0f - num;
6016 }
6017}
static ushort HalfToUInt16Bits(Half value)
static ulong DoubleToUInt64Bits(double value)
static double UInt64BitsToDouble(ulong value)
static uint SingleToUInt32Bits(float value)
static float UInt32BitsToSingle(uint value)
static unsafe void ZeroMemory(byte *dest, nuint len)
Definition Buffer.cs:188
static void Memmove(ref byte dest, ref byte src, nuint len)
Definition Buffer.cs:215
static NumberFormatInfo GetInstance(IFormatProvider? formatProvider)
static bool IsHexChar(int c)
static int FromChar(int c)
static byte Clamp(byte value, byte min, byte max)
Definition Math.cs:435
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static double Ceiling(double a)
static double Abs(double value)
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 readonly short[] s_CachedPowersBinaryExponent
Definition Number.cs:797
static bool TryRunSingle(float value, int requestedDigits, ref NumberBuffer number)
Definition Number.cs:894
static bool TryRunDouble(double value, int requestedDigits, ref NumberBuffer number)
Definition Number.cs:838
static bool TryDigitGenShortest(in DiyFp low, in DiyFp w, in DiyFp high, Span< byte > buffer, out int length, out int kappa)
Definition Number.cs:1017
static bool TryRunHalf(Half value, int requestedDigits, ref NumberBuffer number)
Definition Number.cs:866
static DiyFp GetCachedPowerForBinaryExponentRange(int minExponent, int maxExponent, out int decimalExponent)
Definition Number.cs:1057
static bool TryRunShortest(in DiyFp boundaryMinus, in DiyFp w, in DiyFp boundaryPlus, Span< byte > buffer, out int length, out int decimalExponent)
Definition Number.cs:935
static bool TryRoundWeedShortest(Span< byte > buffer, int length, ulong distanceTooHighW, ulong unsafeInterval, ulong rest, ulong tenKappa, ulong unit)
Definition Number.cs:1095
static bool TryDigitGenCounted(in DiyFp w, int requestedDigits, Span< byte > buffer, out int length, out int kappa)
Definition Number.cs:963
static readonly uint[] s_SmallPowersOfTen
Definition Number.cs:836
static bool TryRunCounted(in DiyFp w, int requestedDigits, Span< byte > buffer, out int length, out int decimalExponent)
Definition Number.cs:922
static readonly short[] s_CachedPowersDecimalExponent
Definition Number.cs:810
static bool TryRoundWeedCounted(Span< byte > buffer, int length, ulong rest, ulong tenKappa, ulong unit, ref int kappa)
Definition Number.cs:1065
static readonly ulong[] s_CachedPowersSignificand
Definition Number.cs:823
static uint BiggestPowerTen(uint number, int numberBits, out int exponentPlusOne)
Definition Number.cs:950
static unsafe string Int32ToHexStr(int value, char hexBase, int digits)
Definition Number.cs:2298
static uint High32(ulong value)
Definition Number.cs:3498
static bool ShouldRoundUp(bool lsbBit, bool roundBit, bool hasTailBits)
Definition Number.cs:3854
static unsafe string UInt64ToDecStr(ulong value, int digits)
Definition Number.cs:2606
static uint Int64DivMod1E9(ref ulong value)
Definition Number.cs:3503
static unsafe void UInt32ToNumber(uint value, ref NumberBuffer number)
Definition Number.cs:2345
static bool TryFormatUInt64(ulong value, ReadOnlySpan< char > format, IFormatProvider provider, Span< char > destination, out int charsWritten)
Definition Number.cs:2184
static unsafe string NegativeInt64ToDecStr(long input, int digits, string sNegative)
Definition Number.cs:2484
static ulong NumberToFloatingPointBitsSlow(ref NumberBuffer number, in FloatingPointInfo info, uint positiveExponent, uint integerDigitsPresent, uint fractionalDigitsPresent)
Definition Number.cs:3761
static unsafe bool TryNumberToUInt32(ref NumberBuffer number, ref uint value)
Definition Number.cs:3937
static unsafe bool TryNumberToInt64(ref NumberBuffer number, ref long value)
Definition Number.cs:3900
static unsafe void Int64ToNumber(long input, ref NumberBuffer number)
Definition Number.cs:2450
static ulong RightShiftWithRounding(ulong value, int shift, bool hasZeroTail)
Definition Number.cs:3839
static unsafe ulong NumberToDoubleFloatingPointBits(ref NumberBuffer number, in FloatingPointInfo info)
Definition Number.cs:3693
static unsafe ulong DigitsToUInt64(byte *p, int count)
Definition Number.cs:3682
static unsafe int FindSection(ReadOnlySpan< char > format, int section)
Definition Number.cs:3432
static string FormatHalf(Half value, string format, NumberFormatInfo info)
Definition Number.cs:1803
static unsafe void FormatExponent(ref ValueStringBuilder sb, NumberFormatInfo info, int value, char expChar, int minDigits, bool positiveSign)
Definition Number.cs:3298
static unsafe uint NumberToSingleFloatingPointBits(ref NumberBuffer number, in FloatingPointInfo info)
Definition Number.cs:3736
static unsafe ParsingStatus TryParseInt32Number(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out int result)
Definition Number.cs:4265
static unsafe void UInt64ToNumber(ulong value, ref NumberBuffer number)
Definition Number.cs:2586
static unsafe void RoundNumber(ref NumberBuffer number, int pos, bool isCorrectlyRounded)
Definition Number.cs:3379
static uint Low32(ulong value)
Definition Number.cs:3493
static unsafe bool TryNumberToUInt64(ref NumberBuffer number, ref ulong value)
Definition Number.cs:3967
static unsafe bool TryInt32ToHexStr(int value, char hexBase, int digits, Span< char > destination, out int charsWritten)
Definition Number.cs:2313
static void FormatCurrency(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info)
Definition Number.cs:3146
static unsafe bool TryNumberToDecimal(ref NumberBuffer number, ref decimal value)
Definition Number.cs:5513
static readonly string[] s_singleDigitStringCache
Definition Number.cs:1233
static unsafe void FormatGeneral(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info, char expChar, bool bSuppressScientific)
Definition Number.cs:3315
static bool SpanStartsWith(ReadOnlySpan< char > span, char c)
Definition Number.cs:5656
static unsafe bool TryParseNumber(ref char *str, char *strEnd, NumberStyles styles, ref NumberBuffer number, NumberFormatInfo info)
Definition Number.cs:4041
static void ThrowOverflowOrFormatException(ParsingStatus status, TypeCode type=TypeCode.Empty)
Definition Number.cs:5918
static void FormatNumber(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info)
Definition Number.cs:3261
static Half NumberToHalf(ref NumberBuffer number)
Definition Number.cs:5972
static unsafe bool TryStringToNumber(ReadOnlySpan< char > value, NumberStyles styles, ref NumberBuffer number, NumberFormatInfo info)
Definition Number.cs:5832
static void ThrowOverflowException(TypeCode type)
Definition Number.cs:5924
static unsafe bool TryUInt32ToDecStr(uint value, int digits, Span< char > destination, out int charsWritten)
Definition Number.cs:2420
static unsafe string FormatDecimal(decimal value, ReadOnlySpan< char > format, NumberFormatInfo info)
Definition Number.cs:1551
static unsafe bool TryParseDouble(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out double result)
Definition Number.cs:5665
static unsafe string NegativeInt32ToDecStr(int value, int digits, string sNegative)
Definition Number.cs:2255
static unsafe void AccumulateDecimalDigitsIntoBigInteger(ref NumberBuffer number, uint firstIndex, uint lastIndex, out BigInteger result)
Definition Number.cs:3561
static unsafe bool TryInt64ToHexStr(long value, char hexBase, int digits, Span< char > destination, out int charsWritten)
Definition Number.cs:2561
static ParsingStatus TryParseUInt32IntegerStyle(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out uint result)
Definition Number.cs:4764
static ParsingStatus TryParseUInt64(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out ulong result)
Definition Number.cs:5119
static readonly string[] s_posPercentFormats
Definition Number.cs:1243
static unsafe bool TryNegativeInt64ToDecStr(long input, int digits, string sNegative, Span< char > destination, out int charsWritten)
Definition Number.cs:2510
static unsafe bool TryFormatDecimal(decimal value, ReadOnlySpan< char > format, NumberFormatInfo info, Span< char > destination, out int charsWritten)
Definition Number.cs:1571
static char ParseFormatSpecifier(ReadOnlySpan< char > format, out int digits)
Definition Number.cs:2657
static unsafe char * MatchChars(char *p, char *pEnd, string value)
Definition Number.cs:5877
static bool TryCopyTo(string source, Span< char > destination, out int charsWritten)
Definition Number.cs:1866
static unsafe bool TryNegativeInt32ToDecStr(int value, int digits, string sNegative, Span< char > destination, out int charsWritten)
Definition Number.cs:2274
static ulong ExtractFractionAndBiasedExponent(double value, out int exponent)
Definition Number.cs:3510
static int ParseInt32(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info)
Definition Number.cs:3997
static unsafe char * Int32ToHexChars(char *buffer, uint value, int hexBase, int digits)
Definition Number.cs:2333
static unsafe void NumberToStringFormat(ref ValueStringBuilder sb, ref NumberBuffer number, ReadOnlySpan< char > format, NumberFormatInfo info)
Definition Number.cs:2817
static bool IsWhite(int ch)
Definition Number.cs:5903
static unsafe void FormatScientific(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info, char expChar)
Definition Number.cs:3282
static ParsingStatus TryParseInt32IntegerStyle(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out int result)
Definition Number.cs:4281
static unsafe uint Dragon4(ulong mantissa, int exponent, uint mantissaHighBitIdx, bool hasUnequalMargins, int cutoffNumber, bool isSignificantDigits, Span< byte > buffer, out int decimalExponent)
Definition Number.cs:1335
static ushort ExtractFractionAndBiasedExponent(Half value, out int exponent)
Definition Number.cs:3527
static string FormatUInt32(uint value, string format, IFormatProvider provider)
Definition Number.cs:1975
static unsafe string FormatDouble(ref ValueStringBuilder sb, double value, ReadOnlySpan< char > format, NumberFormatInfo info)
Definition Number.cs:1696
static bool IsSpaceReplacingChar(char c)
Definition Number.cs:5857
static unsafe void DecimalToNumber(ref decimal d, ref NumberBuffer number)
Definition Number.cs:1591
static readonly string[] s_negPercentFormats
Definition Number.cs:1245
static ulong AssembleFloatingPointBits(in FloatingPointInfo info, ulong initialMantissa, int initialExponent, bool hasZeroTail)
Definition Number.cs:3577
static unsafe string Int64ToHexStr(long value, char hexBase, int digits)
Definition Number.cs:2541
static bool TryFormatInt64(long value, ReadOnlySpan< char > format, IFormatProvider provider, Span< char > destination, out int charsWritten)
Definition Number.cs:2099
static string FormatInt32(int value, int hexMask, string format, IFormatProvider provider)
Definition Number.cs:1882
static double NumberToDouble(ref NumberBuffer number)
Definition Number.cs:5949
static unsafe ParsingStatus TryParseUInt32Number(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out uint result)
Definition Number.cs:4748
static uint ParseUInt32(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info)
Definition Number.cs:4019
static bool TrailingZeros(ReadOnlySpan< char > value, int index)
Definition Number.cs:5845
static string Int32ToDecStr(int value)
Definition Number.cs:2246
static Half ParseHalf(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info)
Definition Number.cs:5631
static Exception GetException(ParsingStatus status, TypeCode type)
Definition Number.cs:5929
static unsafe bool TryUInt64ToDecStr(ulong value, int digits, Span< char > destination, out int charsWritten)
Definition Number.cs:2631
static unsafe char * MatchNegativeSignChars(char *p, char *pEnd, NumberFormatInfo info)
Definition Number.cs:5867
static unsafe void FormatFixed(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, int[] groupDigits, string sDecimal, string sGroup)
Definition Number.cs:3170
static bool IsDigit(int ch)
Definition Number.cs:5912
static bool TryFormatSingle(float value, ReadOnlySpan< char > format, NumberFormatInfo info, Span< char > destination, out int charsWritten)
Definition Number.cs:1747
static unsafe void Int32ToNumber(int value, ref NumberBuffer number)
Definition Number.cs:2223
static decimal ParseDecimal(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info)
Definition Number.cs:5502
static unsafe ParsingStatus TryParseUInt64Number(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out ulong result)
Definition Number.cs:5132
static uint ExtractFractionAndBiasedExponent(float value, out int exponent)
Definition Number.cs:3544
static unsafe bool TryParseSingle(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out float result)
Definition Number.cs:5775
static float NumberToSingle(ref NumberBuffer number)
Definition Number.cs:5995
static void Dragon4Single(float value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number)
Definition Number.cs:1312
static bool TryFormatHalf(Half value, ReadOnlySpan< char > format, NumberFormatInfo info, Span< char > destination, out int charsWritten)
Definition Number.cs:1854
static ParsingStatus TryParseUInt64HexNumberStyle(ReadOnlySpan< char > value, NumberStyles styles, out ulong result)
Definition Number.cs:5356
static void Dragon4Half(Half value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number)
Definition Number.cs:1289
static unsafe ushort NumberToHalfFloatingPointBits(ref NumberBuffer number, in FloatingPointInfo info)
Definition Number.cs:3711
static unsafe ParsingStatus TryParseDecimal(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out decimal result)
Definition Number.cs:5640
static char GetHexBase(char fmt)
Definition Number.cs:1877
static bool TryFormatDouble(double value, ReadOnlySpan< char > format, NumberFormatInfo info, Span< char > destination, out int charsWritten)
Definition Number.cs:1619
static double ParseDouble(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info)
Definition Number.cs:5613
static ParsingStatus TryParseUInt64IntegerStyle(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out ulong result)
Definition Number.cs:5148
static bool TryFormatUInt32(uint value, ReadOnlySpan< char > format, IFormatProvider provider, Span< char > destination, out int charsWritten)
Definition Number.cs:2014
static void NumberToString(ref ValueStringBuilder sb, ref NumberBuffer number, char format, int nMaxDigits, NumberFormatInfo info)
Definition Number.cs:2715
static string Int64ToDecStr(long value)
Definition Number.cs:2475
static unsafe bool TryNumberToInt32(ref NumberBuffer number, ref int value)
Definition Number.cs:3863
static readonly string[] s_negNumberFormats
Definition Number.cs:1251
static void Dragon4Double(double value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number)
Definition Number.cs:1266
static ulong ParseUInt64(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info)
Definition Number.cs:4030
static long ParseInt64(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info)
Definition Number.cs:4008
static float ParseSingle(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info)
Definition Number.cs:5622
static readonly double[] s_Pow10DoubleTable
Definition Number.cs:1259
static unsafe byte * UInt32ToDecChars(byte *bufferEnd, uint value, int digits)
Definition Number.cs:2360
static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int precision, NumberFormatInfo info, out bool isSignificantDigits)
Definition Number.cs:1631
static ulong ConvertBigIntegerToFloatingPointBits(ref BigInteger value, in FloatingPointInfo info, uint integerBitsOfPrecision, bool hasNonZeroFractionalPart)
Definition Number.cs:3631
static unsafe string FormatSingle(ref ValueStringBuilder sb, float value, ReadOnlySpan< char > format, NumberFormatInfo info)
Definition Number.cs:1759
static ParsingStatus TryParseInt64IntegerStyle(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out long result)
Definition Number.cs:4492
static ParsingStatus TryParseInt32(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out int result)
Definition Number.cs:4251
static readonly string[] s_posCurrencyFormats
Definition Number.cs:1235
static unsafe char * UInt32ToDecChars(char *bufferEnd, uint value, int digits)
Definition Number.cs:2371
static string FormatSingle(float value, string format, NumberFormatInfo info)
Definition Number.cs:1740
static unsafe string UInt32ToDecStr(uint value, int digits)
Definition Number.cs:2404
static unsafe uint DigitsToUInt32(byte *p, int count)
Definition Number.cs:3671
static void FormatPercent(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info)
Definition Number.cs:3355
static bool TryFormatInt32(int value, int hexMask, ReadOnlySpan< char > format, IFormatProvider provider, Span< char > destination, out int charsWritten)
Definition Number.cs:1929
static ParsingStatus TryParseUInt32(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out uint result)
Definition Number.cs:4735
static readonly float[] s_Pow10SingleTable
Definition Number.cs:1253
static ParsingStatus TryParseInt64(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out long result)
Definition Number.cs:4704
static unsafe string UInt32ToDecStr(uint value)
Definition Number.cs:2382
static unsafe string FormatHalf(ref ValueStringBuilder sb, Half value, ReadOnlySpan< char > format, NumberFormatInfo info)
Definition Number.cs:1810
static string FormatDouble(double value, string format, NumberFormatInfo info)
Definition Number.cs:1612
static readonly string[] s_negCurrencyFormats
Definition Number.cs:1237
static string FormatUInt64(ulong value, string format, IFormatProvider provider)
Definition Number.cs:2145
static string FormatInt64(long value, string format, IFormatProvider provider)
Definition Number.cs:2052
static unsafe ParsingStatus TryParseInt64Number(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out long result)
Definition Number.cs:4718
static unsafe bool TryParseHalf(ReadOnlySpan< char > value, NumberStyles styles, NumberFormatInfo info, out Half result)
Definition Number.cs:5718
static ParsingStatus TryParseUInt32HexNumberStyle(ReadOnlySpan< char > value, NumberStyles styles, out uint result)
Definition Number.cs:4972
static int Log2(uint value)
static int LeadingZeroCount(uint value)
static string Overflow_Int16
Definition SR.cs:1770
static string Overflow_UInt16
Definition SR.cs:1786
static string Overflow_Int32
Definition SR.cs:1772
static string Overflow_SByte
Definition SR.cs:1780
static string Overflow_UInt64
Definition SR.cs:1790
static string Argument_BadFormatSpecifier
Definition SR.cs:488
static string Overflow_Int64
Definition SR.cs:1774
static string Overflow_Byte
Definition SR.cs:1760
static string Format_InvalidString
Definition SR.cs:1354
static string Overflow_Decimal
Definition SR.cs:1766
static string Overflow_UInt32
Definition SR.cs:1788
Definition SR.cs:7
override string ToString()
StringBuilder Append(char value, int repeatCount)
TypeCode
Definition TypeCode.cs:4
static Half NaN
Definition Half.cs:23
static Half NegativeInfinity
Definition Half.cs:21
static bool IsNaN(Half value)
Definition Half.cs:170
static Half Negate(Half value)
Definition Half.cs:513
static bool IsNegative(Half value)
Definition Half.cs:175
static Half PositiveInfinity
Definition Half.cs:19
static bool IsFinite(Half value)
Definition Half.cs:160
static bool DivideGuessTooBig(ulong q, ulong valHi, uint valLo, uint divHi, uint divLo)
Definition Number.cs:453
static void SetZero(out BigInteger result)
Definition Number.cs:620
static unsafe void Pow10(uint exponent, out BigInteger result)
Definition Number.cs:412
unsafe void Multiply10()
Definition Number.cs:555
static readonly int[] s_Pow10BigNumTableIndices
Definition Number.cs:19
static unsafe void SetUInt64(out BigInteger result, ulong value)
Definition Number.cs:603
static unsafe void Multiply(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result)
Definition Number.cs:346
void MultiplyPow10(uint exponent)
Definition Number.cs:579
static unsafe void Add(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result)
Definition Number.cs:53
unsafe void Add(uint value)
Definition Number.cs:498
static unsafe void DivRem(ref BigInteger lhs, ref BigInteger rhs, out BigInteger quo, out BigInteger rem)
Definition Number.cs:136
static uint DivRem32(uint value, out uint remainder)
Definition Number.cs:699
static unsafe void Pow2(uint exponent, out BigInteger result)
Definition Number.cs:400
void Multiply(uint value)
Definition Number.cs:539
static unsafe uint SubtractDivisor(ref BigInteger lhs, int lhsStartIndex, ref BigInteger rhs, ulong q)
Definition Number.cs:478
static unsafe void SetValue(out BigInteger result, ref BigInteger value)
Definition Number.cs:615
static unsafe uint AddDivisor(ref BigInteger lhs, int lhsStartIndex, ref BigInteger rhs)
Definition Number.cs:438
unsafe fixed uint _blocks[115]
Definition Number.cs:51
static readonly uint[] s_Pow10UInt32Table
Definition Number.cs:17
unsafe void Clear(uint length)
Definition Number.cs:694
static unsafe uint CountSignificantBits(ref BigInteger value)
Definition Number.cs:126
static unsafe int Compare(ref BigInteger lhs, ref BigInteger rhs)
Definition Number.cs:88
unsafe void ShiftLeft(uint shift)
Definition Number.cs:625
static uint CountSignificantBits(ulong value)
Definition Number.cs:121
unsafe uint GetBlock(uint index)
Definition Number.cs:524
unsafe uint ToUInt32()
Definition Number.cs:672
unsafe ulong ToUInt64()
Definition Number.cs:681
static unsafe void SetUInt32(out BigInteger result, uint value)
Definition Number.cs:592
static uint CountSignificantBits(uint value)
Definition Number.cs:116
static unsafe uint HeuristicDivide(ref BigInteger dividend, ref BigInteger divisor)
Definition Number.cs:258
static readonly uint[] s_Pow10BigNumTable
Definition Number.cs:21
static unsafe void Multiply(ref BigInteger lhs, uint value, out BigInteger result)
Definition Number.cs:310
void Multiply(ref BigInteger value)
Definition Number.cs:544
DiyFp(double value)
Definition Number.cs:733
readonly int e
Definition Number.cs:710
DiyFp(ulong f, int e)
Definition Number.cs:748
void GetBoundaries(int implicitBitIndex, out DiyFp mMinus, out DiyFp mPlus)
Definition Number.cs:780
static DiyFp CreateAndGetBoundaries(Half value, out DiyFp mMinus, out DiyFp mPlus)
Definition Number.cs:726
DiyFp(float value)
Definition Number.cs:738
readonly ulong f
Definition Number.cs:708
DiyFp Normalize()
Definition Number.cs:769
static DiyFp CreateAndGetBoundaries(float value, out DiyFp mMinus, out DiyFp mPlus)
Definition Number.cs:719
DiyFp Multiply(in DiyFp other)
Definition Number.cs:754
DiyFp(Half value)
Definition Number.cs:743
static DiyFp CreateAndGetBoundaries(double value, out DiyFp mMinus, out DiyFp mPlus)
Definition Number.cs:712
DiyFp Subtract(in DiyFp other)
Definition Number.cs:775
static readonly FloatingPointInfo Half
Definition Number.cs:1185
FloatingPointInfo(ushort denormalMantissaBits, ushort exponentBits, int maxBinaryExponent, int exponentBias, ulong infinityBits)
Definition Number.cs:1210
static readonly FloatingPointInfo Double
Definition Number.cs:1181
static readonly FloatingPointInfo Single
Definition Number.cs:1183
readonly ushort _003CExponentBits_003Ek__BackingField
Definition Number.cs:1188
unsafe byte * GetDigitsPointer()
Definition Number.cs:1141
unsafe NumberBuffer(NumberBufferKind kind, byte *digits, int digitsLength)
Definition Number.cs:1130
NumberBufferKind Kind
Definition Number.cs:1126
override string ToString()
Definition Number.cs:1146
ReadOnlySpan< T > Slice(int start)
void CopyTo(Span< T > destination)
Definition Span.cs:224
int Length
Definition Span.cs:70
bool TryCopyTo(Span< char > destination, out int charsWritten)