Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
SqlDecimal.cs
Go to the documentation of this file.
3using System.Xml;
6
8
9[XmlSchemaProvider("GetXsdType")]
11{
12 internal byte _bStatus;
13
14 internal byte _bLen;
15
16 internal byte _bPrec;
17
18 internal byte _bScale;
19
20 internal uint _data1;
21
22 internal uint _data2;
23
24 internal uint _data3;
25
26 internal uint _data4;
27
28 public static readonly byte MaxPrecision = 38;
29
30 public static readonly byte MaxScale = 38;
31
32 private static readonly uint[] s_rgulShiftBase = new uint[9] { 10u, 100u, 1000u, 10000u, 100000u, 1000000u, 10000000u, 100000000u, 1000000000u };
33
34 private static readonly uint[] s_decimalHelpersLo = new uint[38]
35 {
36 10u, 100u, 1000u, 10000u, 100000u, 1000000u, 10000000u, 100000000u, 1000000000u, 1410065408u,
37 1215752192u, 3567587328u, 1316134912u, 276447232u, 2764472320u, 1874919424u, 1569325056u, 2808348672u, 2313682944u, 1661992960u,
38 3735027712u, 2990538752u, 4135583744u, 2701131776u, 1241513984u, 3825205248u, 3892314112u, 268435456u, 2684354560u, 1073741824u,
39 2147483648u, 0u, 0u, 0u, 0u, 0u, 0u, 0u
40 };
41
42 private static readonly uint[] s_decimalHelpersMid = new uint[38]
43 {
44 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 2u,
45 23u, 232u, 2328u, 23283u, 232830u, 2328306u, 23283064u, 232830643u, 2328306436u, 1808227885u,
46 902409669u, 434162106u, 46653770u, 466537709u, 370409800u, 3704098002u, 2681241660u, 1042612833u, 1836193738u, 1182068202u,
47 3230747430u, 2242703233u, 952195850u, 932023908u, 730304488u, 3008077584u, 16004768u, 160047680u
48 };
49
50 private static readonly uint[] s_decimalHelpersHi = new uint[38]
51 {
52 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
53 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 5u,
54 54u, 542u, 5421u, 54210u, 542101u, 5421010u, 54210108u, 542101086u, 1126043566u, 2670501072u,
55 935206946u, 762134875u, 3326381459u, 3199043520u, 1925664130u, 2076772117u, 3587851993u, 1518781562u
56 };
57
58 private static readonly uint[] s_decimalHelpersHiHi = new uint[38]
59 {
60 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
61 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
62 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 1u, 12u,
63 126u, 1262u, 12621u, 126217u, 1262177u, 12621774u, 126217744u, 1262177448u
64 };
65
66 public static readonly SqlDecimal Null = new SqlDecimal(fNull: true);
67
68 public static readonly SqlDecimal MinValue = Parse("-99999999999999999999999999999999999999");
69
70 public static readonly SqlDecimal MaxValue = Parse("99999999999999999999999999999999999999");
71
72 public bool IsNull => (_bStatus & 1) == 0;
73
74 public decimal Value => ToDecimal();
75
76 public bool IsPositive
77 {
78 get
79 {
80 if (IsNull)
81 {
82 throw new SqlNullValueException();
83 }
84 return (_bStatus & 2) == 0;
85 }
86 }
87
88 public byte Precision
89 {
90 get
91 {
92 if (IsNull)
93 {
94 throw new SqlNullValueException();
95 }
96 return _bPrec;
97 }
98 }
99
100 public byte Scale
101 {
102 get
103 {
104 if (IsNull)
105 {
106 throw new SqlNullValueException();
107 }
108 return _bScale;
109 }
110 }
111
112 public int[] Data
113 {
114 get
115 {
116 if (IsNull)
117 {
118 throw new SqlNullValueException();
119 }
120 return new int[4]
121 {
122 (int)_data1,
123 (int)_data2,
124 (int)_data3,
125 (int)_data4
126 };
127 }
128 }
129
130 public byte[] BinData
131 {
132 get
133 {
134 if (IsNull)
135 {
136 throw new SqlNullValueException();
137 }
138 int data = (int)_data1;
139 int data2 = (int)_data2;
140 int data3 = (int)_data3;
141 int data4 = (int)_data4;
142 byte[] array = new byte[16]
143 {
144 (byte)((uint)data & 0xFFu),
145 0,
146 0,
147 0,
148 0,
149 0,
150 0,
151 0,
152 0,
153 0,
154 0,
155 0,
156 0,
157 0,
158 0,
159 0
160 };
161 data >>= 8;
162 array[1] = (byte)((uint)data & 0xFFu);
163 data >>= 8;
164 array[2] = (byte)((uint)data & 0xFFu);
165 data >>= 8;
166 array[3] = (byte)((uint)data & 0xFFu);
167 array[4] = (byte)((uint)data2 & 0xFFu);
168 data2 >>= 8;
169 array[5] = (byte)((uint)data2 & 0xFFu);
170 data2 >>= 8;
171 array[6] = (byte)((uint)data2 & 0xFFu);
172 data2 >>= 8;
173 array[7] = (byte)((uint)data2 & 0xFFu);
174 array[8] = (byte)((uint)data3 & 0xFFu);
175 data3 >>= 8;
176 array[9] = (byte)((uint)data3 & 0xFFu);
177 data3 >>= 8;
178 array[10] = (byte)((uint)data3 & 0xFFu);
179 data3 >>= 8;
180 array[11] = (byte)((uint)data3 & 0xFFu);
181 array[12] = (byte)((uint)data4 & 0xFFu);
182 data4 >>= 8;
183 array[13] = (byte)((uint)data4 & 0xFFu);
184 data4 >>= 8;
185 array[14] = (byte)((uint)data4 & 0xFFu);
186 data4 >>= 8;
187 array[15] = (byte)((uint)data4 & 0xFFu);
188 return array;
189 }
190 }
191
192 private static ReadOnlySpan<byte> RgCLenFromPrec => new byte[38]
193 {
194 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
195 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
196 3, 3, 3, 3, 3, 3, 3, 3, 4, 4,
197 4, 4, 4, 4, 4, 4, 4, 4
198 };
199
200 private byte CalculatePrecision()
201 {
202 uint[] array;
203 uint num2;
204 int num;
205 if (_data4 != 0)
206 {
207 num = 33;
209 num2 = _data4;
210 }
211 else if (_data3 != 0)
212 {
213 num = 24;
215 num2 = _data3;
216 }
217 else if (_data2 != 0)
218 {
219 num = 15;
221 num2 = _data2;
222 }
223 else
224 {
225 num = 5;
227 num2 = _data1;
228 }
229 if (num2 < array[num])
230 {
231 num -= 2;
232 if (num2 < array[num])
233 {
234 num -= 2;
235 num = ((num2 >= array[num]) ? (num + 1) : (num - 1));
236 }
237 else
238 {
239 num++;
240 }
241 }
242 else
243 {
244 num += 2;
245 num = ((num2 >= array[num]) ? (num + 1) : (num - 1));
246 }
247 if (num2 >= array[num])
248 {
249 num++;
250 if (num == 37 && num2 >= array[num])
251 {
252 num++;
253 }
254 }
255 byte b = (byte)(num + 1);
256 if (b > 1 && VerifyPrecision((byte)(b - 1)))
257 {
258 b--;
259 }
260 return Math.Max(b, _bScale);
261 }
262
263 private bool VerifyPrecision(byte precision)
264 {
265 int num = checked(precision - 1);
266 if (_data4 < s_decimalHelpersHiHi[num])
267 {
268 return true;
269 }
270 if (_data4 == s_decimalHelpersHiHi[num])
271 {
272 if (_data3 < s_decimalHelpersHi[num])
273 {
274 return true;
275 }
276 if (_data3 == s_decimalHelpersHi[num])
277 {
278 if (_data2 < s_decimalHelpersMid[num])
279 {
280 return true;
281 }
283 {
284 return true;
285 }
286 }
287 }
288 return false;
289 }
290
291 private SqlDecimal(bool fNull)
292 {
293 _bLen = (_bPrec = (_bScale = 0));
294 _bStatus = 0;
295 _data1 = (_data2 = (_data3 = (_data4 = 0u)));
296 }
297
298 public SqlDecimal(decimal value)
299 {
300 _bStatus = 1;
302 decimal.GetBits(value, destination);
303 uint num = (uint)destination[3];
304 _data1 = (uint)destination[0];
305 _data2 = (uint)destination[1];
306 _data3 = (uint)destination[2];
307 _data4 = 0u;
308 _bStatus |= (byte)(((num & 0x80000000u) == 2147483648u) ? 2 : 0);
309 if (_data3 != 0)
310 {
311 _bLen = 3;
312 }
313 else if (_data2 != 0)
314 {
315 _bLen = 2;
316 }
317 else
318 {
319 _bLen = 1;
320 }
321 _bScale = (byte)((int)(num & 0xFF0000) >> 16);
322 _bPrec = 0;
324 }
325
326 public SqlDecimal(int value)
327 {
328 _bStatus = 1;
329 uint data = (uint)value;
330 if (value < 0)
331 {
332 _bStatus |= 2;
333 if (value != int.MinValue)
334 {
335 data = (uint)(-value);
336 }
337 }
338 _data1 = data;
339 _data2 = (_data3 = (_data4 = 0u));
340 _bLen = 1;
342 _bScale = 0;
343 }
344
345 public SqlDecimal(long value)
346 {
347 _bStatus = 1;
348 ulong num = (ulong)value;
349 if (value < 0)
350 {
351 _bStatus |= 2;
352 if (value != long.MinValue)
353 {
354 num = (ulong)(-value);
355 }
356 }
357 _data1 = (uint)num;
358 _data2 = (uint)(num >> 32);
359 _data3 = (_data4 = 0u);
360 _bLen = (byte)((_data2 == 0) ? 1u : 2u);
361 _bPrec = BGetPrecUI8(num);
362 _bScale = 0;
363 }
364
365 public SqlDecimal(byte bPrecision, byte bScale, bool fPositive, int[] bits)
366 {
368 if (bits == null)
369 {
370 throw new ArgumentNullException("bits");
371 }
372 if (bits.Length != 4)
373 {
375 }
377 _bScale = bScale;
378 _data1 = (uint)bits[0];
379 _data2 = (uint)bits[1];
380 _data3 = (uint)bits[2];
381 _data4 = (uint)bits[3];
382 _bLen = 1;
383 for (int num = 3; num >= 0; num--)
384 {
385 if (bits[num] != 0)
386 {
387 _bLen = (byte)(num + 1);
388 break;
389 }
390 }
391 _bStatus = 1;
392 if (!fPositive)
393 {
394 _bStatus |= 2;
395 }
396 if (FZero())
397 {
398 SetPositive();
399 }
401 {
403 }
404 }
405
406 public SqlDecimal(byte bPrecision, byte bScale, bool fPositive, int data1, int data2, int data3, int data4)
407 {
410 _bScale = bScale;
411 _data1 = (uint)data1;
412 _data2 = (uint)data2;
413 _data3 = (uint)data3;
414 _data4 = (uint)data4;
415 _bLen = 1;
416 if (data4 == 0)
417 {
418 if (data3 == 0)
419 {
420 if (data2 == 0)
421 {
422 _bLen = 1;
423 }
424 else
425 {
426 _bLen = 2;
427 }
428 }
429 else
430 {
431 _bLen = 3;
432 }
433 }
434 else
435 {
436 _bLen = 4;
437 }
438 _bStatus = 1;
439 if (!fPositive)
440 {
441 _bStatus |= 2;
442 }
443 if (FZero())
444 {
445 SetPositive();
446 }
448 {
450 }
451 }
452
453 public SqlDecimal(double dVal)
454 : this(fNull: false)
455 {
456 _bStatus = 1;
457 if (dVal < 0.0)
458 {
459 dVal = 0.0 - dVal;
460 _bStatus |= 2;
461 }
462 if (dVal >= 1E+38)
463 {
465 }
466 double num = Math.Floor(dVal);
467 double num2 = dVal - num;
468 _bPrec = 38;
469 _bLen = 1;
470 if (num > 0.0)
471 {
472 dVal = Math.Floor(num / 4294967296.0);
473 _data1 = (uint)(num - dVal * 4294967296.0);
474 num = dVal;
475 if (num > 0.0)
476 {
477 dVal = Math.Floor(num / 4294967296.0);
478 _data2 = (uint)(num - dVal * 4294967296.0);
479 num = dVal;
480 _bLen++;
481 if (num > 0.0)
482 {
483 dVal = Math.Floor(num / 4294967296.0);
484 _data3 = (uint)(num - dVal * 4294967296.0);
485 num = dVal;
486 _bLen++;
487 if (num > 0.0)
488 {
489 dVal = Math.Floor(num / 4294967296.0);
490 _data4 = (uint)(num - dVal * 4294967296.0);
491 num = dVal;
492 _bLen++;
493 }
494 }
495 }
496 }
497 uint num3 = (uint)((!FZero()) ? CalculatePrecision() : 0);
498 if (num3 > 17)
499 {
500 uint num4 = num3 - 17;
501 uint num5;
502 do
503 {
504 num5 = DivByULong(10u);
505 num4--;
506 }
507 while (num4 != 0);
508 num4 = num3 - 17;
509 if (num5 >= 5)
510 {
511 AddULong(1u);
513 }
514 do
515 {
516 MultByULong(10u);
517 num4--;
518 }
519 while (num4 != 0);
520 }
521 _bScale = (byte)((num3 < 17) ? (17 - num3) : 0u);
522 _bPrec = (byte)(num3 + _bScale);
523 if (_bScale > 0)
524 {
525 num3 = _bScale;
526 do
527 {
528 uint num6 = ((num3 >= 9) ? 9u : num3);
529 num2 *= (double)s_rgulShiftBase[num6 - 1];
530 num3 -= num6;
532 AddULong((uint)num2);
533 num2 -= Math.Floor(num2);
534 }
535 while (num3 != 0);
536 }
537 if (num2 >= 0.5)
538 {
539 AddULong(1u);
540 }
541 if (FZero())
542 {
543 SetPositive();
544 }
545 }
546
548 {
550 _bLen = bLen;
551 _bPrec = bPrec;
552 _bScale = bScale;
553 _data1 = rglData[0];
554 _data2 = rglData[1];
555 _data3 = rglData[2];
556 _data4 = rglData[3];
557 _bStatus = 1;
558 if (!fPositive)
559 {
560 _bStatus |= 2;
561 }
562 if (FZero())
563 {
564 SetPositive();
565 }
566 }
567
568 private void SetPositive()
569 {
570 _bStatus &= 253;
571 }
572
573 private void SetSignBit(bool fPositive)
574 {
575 _bStatus = (byte)(fPositive ? (_bStatus & 0xFDu) : (_bStatus | 2u));
576 }
577
578 public override string ToString()
579 {
580 if (IsNull)
581 {
582 return SQLResource.NullString;
583 }
585 int ciulU = _bLen;
586 Span<char> span = stackalloc char[39];
587 span.Clear();
588 int num = 0;
589 while (ciulU > 1 || rgulU[0] != 0)
590 {
592 span[num++] = ChFromDigit(iulR);
593 }
594 while (num <= _bScale)
595 {
596 span[num++] = ChFromDigit(0u);
597 }
598 int num2 = 0;
599 int num3 = 0;
600 if (_bScale > 0)
601 {
602 num2 = 1;
603 }
604 char[] array;
605 if (IsPositive)
606 {
607 array = new char[num2 + num];
608 }
609 else
610 {
611 array = new char[num2 + num + 1];
612 array[num3++] = '-';
613 }
614 while (num > 0)
615 {
616 if (num-- == _bScale)
617 {
618 array[num3++] = '.';
619 }
620 array[num3++] = span[num];
621 }
622 return new string(array);
623 }
624
625 public static SqlDecimal Parse(string s)
626 {
627 if (s == null)
628 {
629 throw new ArgumentNullException("s");
630 }
631 if (s == SQLResource.NullString)
632 {
633 return Null;
634 }
635 SqlDecimal @null = Null;
636 char[] array = s.ToCharArray();
637 int num = array.Length;
638 int num2 = -1;
639 int num3 = 0;
640 @null._bPrec = 1;
641 @null._bScale = 0;
642 @null.SetToZero();
643 while (num != 0 && array[num - 1] == ' ')
644 {
645 num--;
646 }
647 if (num == 0)
648 {
650 }
651 while (array[num3] == ' ')
652 {
653 num3++;
654 num--;
655 }
656 if (array[num3] == '-')
657 {
658 @null.SetSignBit(fPositive: false);
659 num3++;
660 num--;
661 }
662 else
663 {
664 @null.SetSignBit(fPositive: true);
665 if (array[num3] == '+')
666 {
667 num3++;
668 num--;
669 }
670 }
671 while (num > 2 && array[num3] == '0')
672 {
673 num3++;
674 num--;
675 }
676 if (2 == num && '0' == array[num3] && '.' == array[num3 + 1])
677 {
678 array[num3] = '.';
679 array[num3 + 1] = '0';
680 }
681 if (num == 0 || num > 39)
682 {
684 }
685 while (num > 1 && array[num3] == '0')
686 {
687 num3++;
688 num--;
689 }
690 int i;
691 for (i = 0; i < num; i++)
692 {
693 char c = array[num3];
694 num3++;
695 if (c >= '0' && c <= '9')
696 {
697 c = (char)(c - 48);
698 @null.MultByULong(10u);
699 @null.AddULong(c);
700 continue;
701 }
702 if (c == '.' && num2 < 0)
703 {
704 num2 = i;
705 continue;
706 }
708 }
709 if (num2 < 0)
710 {
711 @null._bPrec = (byte)i;
712 @null._bScale = 0;
713 }
714 else
715 {
716 @null._bPrec = (byte)(i - 1);
717 @null._bScale = (byte)(@null._bPrec - num2);
718 }
719 if (@null._bPrec > 38)
720 {
722 }
723 if (@null._bPrec == 0)
724 {
726 }
727 if (@null.FZero())
728 {
729 @null.SetPositive();
730 }
731 return @null;
732 }
733
734 public double ToDouble()
735 {
736 if (IsNull)
737 {
738 throw new SqlNullValueException();
739 }
740 double num = 0.0;
741 num = _data4;
742 num = num * 4294967296.0 + (double)_data3;
743 num = num * 4294967296.0 + (double)_data2;
744 num = num * 4294967296.0 + (double)_data1;
745 num /= Math.Pow(10.0, (int)_bScale);
746 if (!IsPositive)
747 {
748 return 0.0 - num;
749 }
750 return num;
751 }
752
753 private decimal ToDecimal()
754 {
755 if (IsNull)
756 {
757 throw new SqlNullValueException();
758 }
759 if (_data4 != 0 || _bScale > 28)
760 {
762 }
763 return new decimal((int)_data1, (int)_data2, (int)_data3, !IsPositive, _bScale);
764 }
765
766 public static implicit operator SqlDecimal(decimal x)
767 {
768 return new SqlDecimal(x);
769 }
770
771 public static explicit operator SqlDecimal(double x)
772 {
773 return new SqlDecimal(x);
774 }
775
776 public static implicit operator SqlDecimal(long x)
777 {
778 return new SqlDecimal(new decimal(x));
779 }
780
781 public static explicit operator decimal(SqlDecimal x)
782 {
783 return x.Value;
784 }
785
787 {
788 if (x.IsNull)
789 {
790 return Null;
791 }
792 SqlDecimal result = x;
793 if (result.FZero())
794 {
795 result.SetPositive();
796 }
797 else
798 {
799 result.SetSignBit(!result.IsPositive);
800 }
801 return result;
802 }
803
805 {
806 if (x.IsNull || y.IsNull)
807 {
808 return Null;
809 }
810 bool flag = true;
811 bool isPositive = x.IsPositive;
812 bool flag2 = y.IsPositive;
813 int bScale = x._bScale;
814 int bScale2 = y._bScale;
815 int num = Math.Max(x._bPrec - bScale, y._bPrec - bScale2);
816 int num2 = Math.Max(bScale, bScale2);
817 int val = num + num2 + 1;
818 val = Math.Min(MaxPrecision, val);
819 if (val - num < num2)
820 {
821 num2 = val - num;
822 }
823 if (bScale != num2)
824 {
825 x.AdjustScale(num2 - bScale, fRound: true);
826 }
827 if (bScale2 != num2)
828 {
829 y.AdjustScale(num2 - bScale2, fRound: true);
830 }
831 if (!isPositive)
832 {
834 flag2 = !flag2;
835 flag = !flag;
836 }
837 int num3 = x._bLen;
838 int bLen = y._bLen;
839 Span<uint> span = stackalloc uint[4] { x._data1, x._data2, x._data3, x._data4 };
840 Span<uint> span2 = stackalloc uint[4] { y._data1, y._data2, y._data3, y._data4 };
841 byte bLen2;
842 if (flag2)
843 {
844 ulong num4 = 0uL;
845 int i;
846 for (i = 0; i < num3 || i < bLen; i++)
847 {
848 if (i < num3)
849 {
850 num4 += span[i];
851 }
852 if (i < bLen)
853 {
854 num4 += span2[i];
855 }
856 span[i] = (uint)num4;
857 num4 >>= 32;
858 }
859 if (num4 != 0L)
860 {
861 if (i == 4)
862 {
864 }
865 span[i] = (uint)num4;
866 i++;
867 }
868 bLen2 = (byte)i;
869 }
870 else
871 {
872 int num5 = 0;
873 if (x.LAbsCmp(y) < 0)
874 {
875 flag = !flag;
877 span2 = span;
878 span = span3;
879 num3 = bLen;
880 bLen = x._bLen;
881 }
882 ulong num4 = 4294967296uL;
883 for (int i = 0; i < num3 || i < bLen; i++)
884 {
885 if (i < num3)
886 {
887 num4 += span[i];
888 }
889 if (i < bLen)
890 {
891 num4 -= span2[i];
892 }
893 span[i] = (uint)num4;
894 if (span[i] != 0)
895 {
896 num5 = i;
897 }
898 num4 >>= 32;
899 num4 += uint.MaxValue;
900 }
901 bLen2 = (byte)(num5 + 1);
902 }
903 SqlDecimal result = new SqlDecimal(span, bLen2, (byte)val, (byte)num2, flag);
904 if (result.FGt10_38() || result.CalculatePrecision() > 38)
905 {
907 }
908 if (result.FZero())
909 {
910 result.SetPositive();
911 }
912 return result;
913 }
914
916 {
917 return x + -y;
918 }
919
921 {
922 if (x.IsNull || y.IsNull)
923 {
924 return Null;
925 }
926 int bLen = y._bLen;
927 int num = x._bScale + y._bScale;
928 int num2 = num;
929 int num3 = x._bPrec - x._bScale + (y._bPrec - y._bScale) + 1;
930 int num4 = num2 + num3;
931 if (num4 > 38)
932 {
933 num4 = 38;
934 }
935 if (num2 > 38)
936 {
937 num2 = 38;
938 }
939 num2 = Math.Min(num4 - num3, num2);
940 num2 = Math.Max(num2, Math.Min(num, 6));
941 int num5 = num2 - num;
943 Span<uint> span = stackalloc uint[4] { x._data1, x._data2, x._data3, x._data4 };
945 span = stackalloc uint[4] { y._data1, y._data2, y._data3, y._data4 };
947 Span<uint> span2 = stackalloc uint[9];
948 span2.Clear();
949 int num6 = 0;
950 for (int i = 0; i < x._bLen; i++)
951 {
952 uint num7 = readOnlySpan[i];
953 ulong num8 = 0uL;
954 num6 = i;
955 for (int j = 0; j < bLen; j++)
956 {
957 ulong num9 = num8 + span2[num6];
958 ulong num10 = readOnlySpan2[j];
959 num8 = num7 * num10;
960 num8 += num9;
961 num9 = ((num8 >= num9) ? 0 : 4294967296uL);
962 span2[num6++] = (uint)num8;
963 num8 = (num8 >> 32) + num9;
964 }
965 if (num8 != 0L)
966 {
967 span2[num6++] = (uint)num8;
968 }
969 }
970 while (span2[num6] == 0 && num6 > 0)
971 {
972 num6--;
973 }
974 int ciulU = num6 + 1;
975 SqlDecimal result;
976 if (num5 != 0)
977 {
978 if (num5 < 0)
979 {
980 uint num11;
981 uint iulR;
982 do
983 {
984 if (num5 <= -9)
985 {
987 num5 += 9;
988 }
989 else
990 {
991 num11 = s_rgulShiftBase[-num5 - 1];
992 num5 = 0;
993 }
995 }
996 while (num5 != 0);
997 if (ciulU > 4)
998 {
1000 }
1001 for (num6 = ciulU; num6 < 4; num6++)
1002 {
1003 span2[num6] = 0u;
1004 }
1005 result = new SqlDecimal(span2, (byte)ciulU, (byte)num4, (byte)num2, fPositive);
1006 if (result.FGt10_38())
1007 {
1009 }
1010 if (iulR >= num11 / 2)
1011 {
1012 result.AddULong(1u);
1013 }
1014 if (result.FZero())
1015 {
1016 result.SetPositive();
1017 }
1018 return result;
1019 }
1020 if (ciulU > 4)
1021 {
1023 }
1024 for (num6 = ciulU; num6 < 4; num6++)
1025 {
1026 span2[num6] = 0u;
1027 }
1028 result = new SqlDecimal(span2, (byte)ciulU, (byte)num4, (byte)num, fPositive);
1029 if (result.FZero())
1030 {
1031 result.SetPositive();
1032 }
1033 result.AdjustScale(num5, fRound: true);
1034 return result;
1035 }
1036 if (ciulU > 4)
1037 {
1039 }
1040 for (num6 = ciulU; num6 < 4; num6++)
1041 {
1042 span2[num6] = 0u;
1043 }
1044 result = new SqlDecimal(span2, (byte)ciulU, (byte)num4, (byte)num2, fPositive);
1045 if (result.FGt10_38())
1046 {
1048 }
1049 if (result.FZero())
1050 {
1051 result.SetPositive();
1052 }
1053 return result;
1054 }
1055
1057 {
1058 if (x.IsNull || y.IsNull)
1059 {
1060 return Null;
1061 }
1062 if (y.FZero())
1063 {
1065 }
1066 bool fPositive = x.IsPositive == y.IsPositive;
1067 int bScale = x._bScale;
1068 int bPrec = x._bPrec;
1069 int num = Math.Max(x._bScale + y._bPrec + 1, 6);
1070 int val = x._bPrec - x._bScale + y._bScale;
1071 int num2 = num + x._bPrec + y._bPrec + 1;
1072 int val2 = Math.Min(num, 6);
1073 val = Math.Min(val, 38);
1074 num2 = val + num;
1075 if (num2 > 38)
1076 {
1077 num2 = 38;
1078 }
1079 num = Math.Min(num2 - val, num);
1080 num = Math.Max(num, val2);
1081 int digits = num - x._bScale + y._bScale;
1082 x.AdjustScale(digits, fRound: true);
1083 Span<uint> span = stackalloc uint[4] { x._data1, x._data2, x._data3, x._data4 };
1084 Span<uint> rgulD = stackalloc uint[4] { y._data1, y._data2, y._data3, y._data4 };
1085 Span<uint> rgulR = stackalloc uint[5];
1086 Span<uint> span2 = stackalloc uint[4];
1087 rgulR.Clear();
1088 span2.Clear();
1091 SqlDecimal result = new SqlDecimal(span2, (byte)ciulQ, (byte)num2, (byte)num, fPositive);
1092 if (result.FZero())
1093 {
1094 result.SetPositive();
1095 }
1096 return result;
1097 }
1098
1099 public static explicit operator SqlDecimal(SqlBoolean x)
1100 {
1101 if (!x.IsNull)
1102 {
1103 return new SqlDecimal(x.ByteValue);
1104 }
1105 return Null;
1106 }
1107
1108 public static implicit operator SqlDecimal(SqlByte x)
1109 {
1110 if (!x.IsNull)
1111 {
1112 return new SqlDecimal(x.Value);
1113 }
1114 return Null;
1115 }
1116
1117 public static implicit operator SqlDecimal(SqlInt16 x)
1118 {
1119 if (!x.IsNull)
1120 {
1121 return new SqlDecimal(x.Value);
1122 }
1123 return Null;
1124 }
1125
1126 public static implicit operator SqlDecimal(SqlInt32 x)
1127 {
1128 if (!x.IsNull)
1129 {
1130 return new SqlDecimal(x.Value);
1131 }
1132 return Null;
1133 }
1134
1135 public static implicit operator SqlDecimal(SqlInt64 x)
1136 {
1137 if (!x.IsNull)
1138 {
1139 return new SqlDecimal(x.Value);
1140 }
1141 return Null;
1142 }
1143
1144 public static implicit operator SqlDecimal(SqlMoney x)
1145 {
1146 if (!x.IsNull)
1147 {
1148 return new SqlDecimal(x.ToDecimal());
1149 }
1150 return Null;
1151 }
1152
1153 public static explicit operator SqlDecimal(SqlSingle x)
1154 {
1155 if (!x.IsNull)
1156 {
1157 return new SqlDecimal(x.Value);
1158 }
1159 return Null;
1160 }
1161
1162 public static explicit operator SqlDecimal(SqlDouble x)
1163 {
1164 if (!x.IsNull)
1165 {
1166 return new SqlDecimal(x.Value);
1167 }
1168 return Null;
1169 }
1170
1171 public static explicit operator SqlDecimal(SqlString x)
1172 {
1173 if (!x.IsNull)
1174 {
1175 return Parse(x.Value);
1176 }
1177 return Null;
1178 }
1179
1180 private static void ZeroToMaxLen(Span<uint> rgulData, int cUI4sCur)
1181 {
1182 switch (cUI4sCur)
1183 {
1184 case 1:
1185 rgulData[1] = (rgulData[2] = (rgulData[3] = 0u));
1186 break;
1187 case 2:
1188 rgulData[2] = (rgulData[3] = 0u);
1189 break;
1190 case 3:
1191 rgulData[3] = 0u;
1192 break;
1193 }
1194 }
1195
1196 private static byte CLenFromPrec(byte bPrec)
1197 {
1198 return RgCLenFromPrec[bPrec - 1];
1199 }
1200
1201 private bool FZero()
1202 {
1203 if (_data1 == 0)
1204 {
1205 return _bLen <= 1;
1206 }
1207 return false;
1208 }
1209
1210 private bool FGt10_38()
1211 {
1212 if ((long)_data4 >= 1262177448L && _bLen == 4)
1213 {
1214 if ((long)_data4 <= 1262177448L && (long)_data3 <= 1518781562L)
1215 {
1216 if ((ulong)_data3 == 1518781562)
1217 {
1218 return (long)_data2 >= 160047680L;
1219 }
1220 return false;
1221 }
1222 return true;
1223 }
1224 return false;
1225 }
1226
1228 {
1229 if ((long)rglData[3] >= 1262177448L)
1230 {
1231 if ((long)rglData[3] <= 1262177448L && (long)rglData[2] <= 1518781562L)
1232 {
1233 if ((ulong)rglData[2] == 1518781562)
1234 {
1235 return (long)rglData[1] >= 160047680L;
1236 }
1237 return false;
1238 }
1239 return true;
1240 }
1241 return false;
1242 }
1243
1244 private static byte BGetPrecUI4(uint value)
1245 {
1246 int num = ((value < 10000) ? ((value >= 100) ? ((value >= 1000) ? 4 : 3) : ((value < 10) ? 1 : 2)) : ((value >= 100000000) ? ((value >= 1000000000) ? 10 : 9) : ((value >= 1000000) ? ((value >= 10000000) ? 8 : 7) : ((value >= 100000) ? 6 : 5))));
1247 return (byte)num;
1248 }
1249
1250 private static byte BGetPrecUI8(ulong dwlVal)
1251 {
1252 int num;
1253 if (dwlVal >= 100000000)
1254 {
1255 num = ((dwlVal < 10000000000000000L) ? ((dwlVal < 1000000000000L) ? ((dwlVal >= 10000000000L) ? ((dwlVal >= 100000000000L) ? 12 : 11) : ((dwlVal >= 1000000000) ? 10 : 9)) : ((dwlVal >= 100000000000000L) ? ((dwlVal >= 1000000000000000L) ? 16 : 15) : ((dwlVal >= 10000000000000L) ? 14 : 13))) : ((dwlVal >= 1000000000000000000L) ? ((dwlVal >= 10000000000000000000uL) ? 20 : 19) : ((dwlVal >= 100000000000000000L) ? 18 : 17)));
1256 }
1257 else
1258 {
1259 uint num2 = (uint)dwlVal;
1260 num = ((num2 < 10000) ? ((num2 >= 100) ? ((num2 >= 1000) ? 4 : 3) : ((num2 < 10) ? 1 : 2)) : ((num2 >= 1000000) ? ((num2 >= 10000000) ? 8 : 7) : ((num2 >= 100000) ? 6 : 5)));
1261 }
1262 return (byte)num;
1263 }
1264
1265 private void AddULong(uint ulAdd)
1266 {
1267 ulong num = ulAdd;
1268 int bLen = _bLen;
1270 int num2 = 0;
1271 do
1272 {
1273 num += span[num2];
1274 span[num2] = (uint)num;
1275 num >>= 32;
1276 if (num == 0L)
1277 {
1279 return;
1280 }
1281 num2++;
1282 }
1283 while (num2 < bLen);
1284 if (num2 == 4)
1285 {
1287 }
1288 span[num2] = (uint)num;
1289 _bLen++;
1290 if (FGt10_38(span))
1291 {
1293 }
1295 }
1296
1297 private void MultByULong(uint uiMultiplier)
1298 {
1299 int bLen = _bLen;
1300 ulong num = 0uL;
1301 ulong num2 = 0uL;
1303 for (int i = 0; i < bLen; i++)
1304 {
1305 ulong num3 = span[i];
1307 num += num2;
1308 num2 = ((num >= num2) ? 0 : 4294967296uL);
1309 span[i] = (uint)num;
1310 num = (num >> 32) + num2;
1311 }
1312 if (num != 0L)
1313 {
1314 if (bLen == 4)
1315 {
1317 }
1318 span[bLen] = (uint)num;
1319 _bLen++;
1320 }
1321 if (FGt10_38(span))
1322 {
1324 }
1326 }
1327
1328 private uint DivByULong(uint iDivisor)
1329 {
1330 ulong num = iDivisor;
1331 ulong num2 = 0uL;
1332 uint num3 = 0u;
1333 bool flag = true;
1334 if (num == 0L)
1335 {
1337 }
1339 for (int num4 = _bLen; num4 > 0; num4--)
1340 {
1341 num2 = (num2 << 32) + span[num4 - 1];
1342 num3 = (uint)(num2 / num);
1343 span[num4 - 1] = num3;
1344 num2 %= num;
1345 if (flag && num3 == 0)
1346 {
1347 _bLen--;
1348 }
1349 else
1350 {
1351 flag = false;
1352 }
1353 }
1355 if (flag)
1356 {
1357 _bLen = 1;
1358 }
1359 return (uint)num2;
1360 }
1361
1362 internal void AdjustScale(int digits, bool fRound)
1363 {
1364 bool flag = false;
1365 int num = digits;
1366 if (num + _bScale < 0)
1367 {
1368 throw new SqlTruncateException();
1369 }
1370 if (num + _bScale > 38)
1371 {
1373 }
1374 byte bScale = (byte)(num + _bScale);
1375 byte bPrec = (byte)Math.Min(38, Math.Max(1, num + _bPrec));
1376 if (num > 0)
1377 {
1378 _bScale = bScale;
1379 _bPrec = bPrec;
1380 while (num > 0)
1381 {
1382 uint uiMultiplier;
1383 if (num >= 9)
1384 {
1386 num -= 9;
1387 }
1388 else
1389 {
1390 uiMultiplier = s_rgulShiftBase[num - 1];
1391 num = 0;
1392 }
1394 }
1395 }
1396 else if (num < 0)
1397 {
1398 uint uiMultiplier;
1399 uint num2;
1400 do
1401 {
1402 if (num <= -9)
1403 {
1405 num += 9;
1406 }
1407 else
1408 {
1409 uiMultiplier = s_rgulShiftBase[-num - 1];
1410 num = 0;
1411 }
1413 }
1414 while (num < 0);
1415 flag = num2 >= uiMultiplier / 2;
1416 _bScale = bScale;
1417 _bPrec = bPrec;
1418 }
1419 if (flag && fRound)
1420 {
1421 AddULong(1u);
1422 }
1423 else if (FZero())
1424 {
1425 SetPositive();
1426 }
1427 }
1428
1429 public static SqlDecimal AdjustScale(SqlDecimal n, int digits, bool fRound)
1430 {
1431 if (n.IsNull)
1432 {
1433 return Null;
1434 }
1435 SqlDecimal result = n;
1436 result.AdjustScale(digits, fRound);
1437 return result;
1438 }
1439
1440 public static SqlDecimal ConvertToPrecScale(SqlDecimal n, int precision, int scale)
1441 {
1442 CheckValidPrecScale(precision, scale);
1443 if (n.IsNull)
1444 {
1445 return Null;
1446 }
1447 SqlDecimal result = n;
1448 int digits = scale - result._bScale;
1449 result.AdjustScale(digits, fRound: true);
1450 byte b = CLenFromPrec((byte)precision);
1451 if (b < result._bLen)
1452 {
1453 throw new SqlTruncateException();
1454 }
1455 if (b == result._bLen && precision < result.CalculatePrecision())
1456 {
1457 throw new SqlTruncateException();
1458 }
1459 result._bPrec = (byte)precision;
1460 return result;
1461 }
1462
1464 {
1465 int bLen = snumOp._bLen;
1466 int bLen2 = _bLen;
1467 if (bLen != bLen2)
1468 {
1469 if (bLen2 <= bLen)
1470 {
1471 return -1;
1472 }
1473 return 1;
1474 }
1477 span = stackalloc uint[4] { snumOp._data1, snumOp._data2, snumOp._data3, snumOp._data4 };
1479 int num = bLen - 1;
1480 do
1481 {
1482 if (readOnlySpan[num] != readOnlySpan2[num])
1483 {
1484 if (readOnlySpan[num] <= readOnlySpan2[num])
1485 {
1486 return -1;
1487 }
1488 return 1;
1489 }
1490 num--;
1491 }
1492 while (num >= 0);
1493 return 0;
1494 }
1495
1497 {
1498 ciulD = ciulS;
1499 for (int i = 0; i < ciulS; i++)
1500 {
1501 rgulD[i] = rgulS[i];
1502 }
1503 }
1504
1505 private static void MpSet(Span<uint> rgulD, out int ciulD, uint iulN)
1506 {
1507 ciulD = 1;
1508 rgulD[0] = iulN;
1509 }
1510
1512 {
1513 while (ciulU > 1 && rgulU[ciulU - 1] == 0)
1514 {
1515 ciulU--;
1516 }
1517 }
1518
1519 private static void MpMul1(Span<uint> piulD, ref int ciulD, uint iulX)
1520 {
1521 uint num = 0u;
1522 int i;
1523 for (i = 0; i < ciulD; i++)
1524 {
1525 ulong num2 = piulD[i];
1526 ulong x = num + num2 * iulX;
1527 num = HI(x);
1528 piulD[i] = LO(x);
1529 }
1530 if (num != 0)
1531 {
1532 piulD[i] = num;
1533 ciulD++;
1534 }
1535 }
1536
1537 private static void MpDiv1(Span<uint> rgulU, ref int ciulU, uint iulD, out uint iulR)
1538 {
1539 uint num = 0u;
1540 ulong num2 = iulD;
1541 int num3 = ciulU;
1542 while (num3 > 0)
1543 {
1544 num3--;
1545 ulong num4 = ((ulong)num << 32) + rgulU[num3];
1546 rgulU[num3] = (uint)(num4 / num2);
1547 num = (uint)(num4 - rgulU[num3] * num2);
1548 }
1549 iulR = num;
1551 }
1552
1553 internal static ulong DWL(uint lo, uint hi)
1554 {
1555 return lo + ((ulong)hi << 32);
1556 }
1557
1558 private static uint HI(ulong x)
1559 {
1560 return (uint)(x >> 32);
1561 }
1562
1563 private static uint LO(ulong x)
1564 {
1565 return (uint)x;
1566 }
1567
1569 {
1570 if (ciulD == 1 && rgulD[0] == 0)
1571 {
1572 ciulQ = (ciulR = 0);
1573 return;
1574 }
1575 if (ciulU == 1 && ciulD == 1)
1576 {
1577 MpSet(rgulQ, out ciulQ, rgulU[0] / rgulD[0]);
1578 MpSet(rgulR, out ciulR, rgulU[0] % rgulD[0]);
1579 return;
1580 }
1581 if (ciulD > ciulU)
1582 {
1584 MpSet(rgulQ, out ciulQ, 0u);
1585 return;
1586 }
1587 if (ciulU <= 2)
1588 {
1589 ulong num = DWL(rgulU[0], rgulU[1]);
1590 ulong num2 = rgulD[0];
1591 if (ciulD > 1)
1592 {
1593 num2 += (ulong)rgulD[1] << 32;
1594 }
1595 ulong x = num / num2;
1596 rgulQ[0] = LO(x);
1597 rgulQ[1] = HI(x);
1598 ciulQ = ((HI(x) == 0) ? 1 : 2);
1599 x = num % num2;
1600 rgulR[0] = LO(x);
1601 rgulR[1] = HI(x);
1602 ciulR = ((HI(x) == 0) ? 1 : 2);
1603 return;
1604 }
1605 if (ciulD == 1)
1606 {
1609 rgulR[0] = iulR;
1610 ciulR = 1;
1611 return;
1612 }
1613 ciulQ = (ciulR = 0);
1614 if (rgulU != rgulR)
1615 {
1617 }
1618 ciulQ = ciulU - ciulD + 1;
1619 uint num3 = rgulD[ciulD - 1];
1620 rgulR[ciulU] = 0u;
1621 int num4 = ciulU;
1622 uint num5 = (uint)(4294967296uL / (ulong)((long)num3 + 1L));
1623 if (num5 > 1)
1624 {
1626 num3 = rgulD[ciulD - 1];
1628 }
1629 uint num6 = rgulD[ciulD - 2];
1630 do
1631 {
1632 ulong num7 = DWL(rgulR[num4 - 1], rgulR[num4]);
1633 uint num8 = (uint)((num3 != rgulR[num4]) ? (num7 / num3) : uint.MaxValue);
1634 ulong num9 = num8;
1635 uint num10 = (uint)(num7 - num9 * num3);
1636 while (num6 * num9 > DWL(rgulR[num4 - 2], num10))
1637 {
1638 num8--;
1639 if (num10 >= 0 - num3)
1640 {
1641 break;
1642 }
1643 num10 += num3;
1644 num9 = num8;
1645 }
1646 num7 = 4294967296uL;
1647 ulong num11 = 0uL;
1648 int num12 = 0;
1649 int num13 = num4 - ciulD;
1650 while (num12 < ciulD)
1651 {
1652 ulong num14 = rgulD[num12];
1653 num11 += num8 * num14;
1654 num7 += (ulong)((long)rgulR[num13] - (long)LO(num11));
1655 num11 = HI(num11);
1656 rgulR[num13] = LO(num7);
1657 num7 = (ulong)((long)HI(num7) + 4294967296L - 1);
1658 num12++;
1659 num13++;
1660 }
1661 num7 += rgulR[num13] - num11;
1662 rgulR[num13] = LO(num7);
1663 rgulQ[num4 - ciulD] = num8;
1664 if (HI(num7) == 0)
1665 {
1666 rgulQ[num4 - ciulD] = num8 - 1;
1667 uint num15 = 0u;
1668 num12 = 0;
1669 num13 = num4 - ciulD;
1670 while (num12 < ciulD)
1671 {
1672 num7 = (ulong)((long)rgulD[num12] + (long)rgulR[num13] + num15);
1673 num15 = HI(num7);
1674 rgulR[num13] = LO(num7);
1675 num12++;
1676 num13++;
1677 }
1678 rgulR[num13] += num15;
1679 }
1680 num4--;
1681 }
1682 while (num4 >= ciulD);
1684 ciulR = ciulD;
1686 if (num5 > 1)
1687 {
1690 }
1691 }
1692
1694 {
1695 int num = (IsPositive ? 1 : (-1));
1696 int num2 = (snumOp.IsPositive ? 1 : (-1));
1697 if (num != num2)
1698 {
1699 if (num != 1)
1700 {
1701 return EComparison.LT;
1702 }
1703 return EComparison.GT;
1704 }
1705 SqlDecimal sqlDecimal = this;
1707 int num3 = _bScale - snumOp._bScale;
1708 if (num3 < 0)
1709 {
1710 try
1711 {
1712 sqlDecimal.AdjustScale(-num3, fRound: true);
1713 }
1714 catch (OverflowException)
1715 {
1716 return (num > 0) ? EComparison.GT : EComparison.LT;
1717 }
1718 }
1719 else if (num3 > 0)
1720 {
1721 try
1722 {
1723 snumOp2.AdjustScale(num3, fRound: true);
1724 }
1725 catch (OverflowException)
1726 {
1727 return (num <= 0) ? EComparison.GT : EComparison.LT;
1728 }
1729 }
1730 int num4 = sqlDecimal.LAbsCmp(snumOp2);
1731 if (num4 == 0)
1732 {
1733 return EComparison.EQ;
1734 }
1735 int num5 = num * num4;
1736 if (num5 < 0)
1737 {
1738 return EComparison.LT;
1739 }
1740 return EComparison.GT;
1741 }
1742
1743 private static void CheckValidPrecScale(byte bPrec, byte bScale)
1744 {
1746 {
1748 }
1749 }
1750
1751 private static void CheckValidPrecScale(int iPrec, int iScale)
1752 {
1754 {
1756 }
1757 }
1758
1760 {
1761 if (!x.IsNull && !y.IsNull)
1762 {
1763 return new SqlBoolean(x.CompareNm(y) == EComparison.EQ);
1764 }
1765 return SqlBoolean.Null;
1766 }
1767
1769 {
1770 return !(x == y);
1771 }
1772
1774 {
1775 if (!x.IsNull && !y.IsNull)
1776 {
1777 return new SqlBoolean(x.CompareNm(y) == EComparison.LT);
1778 }
1779 return SqlBoolean.Null;
1780 }
1781
1783 {
1784 if (!x.IsNull && !y.IsNull)
1785 {
1786 return new SqlBoolean(x.CompareNm(y) == EComparison.GT);
1787 }
1788 return SqlBoolean.Null;
1789 }
1790
1792 {
1793 if (x.IsNull || y.IsNull)
1794 {
1795 return SqlBoolean.Null;
1796 }
1798 return new SqlBoolean(eComparison == EComparison.LT || eComparison == EComparison.EQ);
1799 }
1800
1802 {
1803 if (x.IsNull || y.IsNull)
1804 {
1805 return SqlBoolean.Null;
1806 }
1808 return new SqlBoolean(eComparison == EComparison.GT || eComparison == EComparison.EQ);
1809 }
1810
1812 {
1813 return x + y;
1814 }
1815
1817 {
1818 return x - y;
1819 }
1820
1822 {
1823 return x * y;
1824 }
1825
1827 {
1828 return x / y;
1829 }
1830
1832 {
1833 return x == y;
1834 }
1835
1837 {
1838 return x != y;
1839 }
1840
1842 {
1843 return x < y;
1844 }
1845
1847 {
1848 return x > y;
1849 }
1850
1852 {
1853 return x <= y;
1854 }
1855
1857 {
1858 return x >= y;
1859 }
1860
1862 {
1863 return (SqlBoolean)this;
1864 }
1865
1867 {
1868 return (SqlByte)this;
1869 }
1870
1872 {
1873 return this;
1874 }
1875
1877 {
1878 return (SqlInt16)this;
1879 }
1880
1882 {
1883 return (SqlInt32)this;
1884 }
1885
1887 {
1888 return (SqlInt64)this;
1889 }
1890
1892 {
1893 return (SqlMoney)this;
1894 }
1895
1897 {
1898 return this;
1899 }
1900
1902 {
1903 return (SqlString)this;
1904 }
1905
1906 private static char ChFromDigit(uint uiDigit)
1907 {
1908 return (char)(uiDigit + 48);
1909 }
1910
1912 {
1913 _data1 = rguiData[0];
1914 _data2 = rguiData[1];
1915 _data3 = rguiData[2];
1916 _data4 = rguiData[3];
1917 }
1918
1919 private void SetToZero()
1920 {
1921 _bLen = 1;
1922 _data1 = (_data2 = (_data3 = (_data4 = 0u)));
1923 _bStatus = 1;
1924 }
1925
1926 private void MakeInteger(out bool fFraction)
1927 {
1928 int num = _bScale;
1929 fFraction = false;
1930 while (num > 0)
1931 {
1932 uint num2;
1933 if (num >= 9)
1934 {
1936 num -= 9;
1937 }
1938 else
1939 {
1940 num2 = DivByULong(s_rgulShiftBase[num - 1]);
1941 num = 0;
1942 }
1943 if (num2 != 0)
1944 {
1945 fFraction = true;
1946 }
1947 }
1948 _bScale = 0;
1949 }
1950
1952 {
1953 if (n.IsNull)
1954 {
1955 return Null;
1956 }
1957 n.SetPositive();
1958 return n;
1959 }
1960
1962 {
1963 if (n.IsNull)
1964 {
1965 return Null;
1966 }
1967 if (n._bScale == 0)
1968 {
1969 return n;
1970 }
1971 n.MakeInteger(out var fFraction);
1972 if (fFraction && n.IsPositive)
1973 {
1974 n.AddULong(1u);
1975 }
1976 if (n.FZero())
1977 {
1978 n.SetPositive();
1979 }
1980 return n;
1981 }
1982
1984 {
1985 if (n.IsNull)
1986 {
1987 return Null;
1988 }
1989 if (n._bScale == 0)
1990 {
1991 return n;
1992 }
1993 n.MakeInteger(out var fFraction);
1994 if (fFraction && !n.IsPositive)
1995 {
1996 n.AddULong(1u);
1997 }
1998 if (n.FZero())
1999 {
2000 n.SetPositive();
2001 }
2002 return n;
2003 }
2004
2005 public static SqlInt32 Sign(SqlDecimal n)
2006 {
2007 if (n.IsNull)
2008 {
2009 return SqlInt32.Null;
2010 }
2011 if (n == new SqlDecimal(0))
2012 {
2013 return SqlInt32.Zero;
2014 }
2015 if (!n.IsNull)
2016 {
2017 if (!n.IsPositive)
2018 {
2019 return new SqlInt32(-1);
2020 }
2021 return new SqlInt32(1);
2022 }
2023 return SqlInt32.Null;
2024 }
2025
2026 private static SqlDecimal Round(SqlDecimal n, int lPosition, bool fTruncate)
2027 {
2028 if (n.IsNull)
2029 {
2030 return Null;
2031 }
2032 if (lPosition >= 0)
2033 {
2034 lPosition = Math.Min(38, lPosition);
2035 if (lPosition >= n._bScale)
2036 {
2037 return n;
2038 }
2039 }
2040 else
2041 {
2042 lPosition = Math.Max(-38, lPosition);
2043 if (lPosition < n._bScale - n._bPrec)
2044 {
2045 n.SetToZero();
2046 return n;
2047 }
2048 }
2049 uint num = 0u;
2050 int num2 = Math.Abs(lPosition - n._bScale);
2051 uint num3 = 1u;
2052 while (num2 > 0)
2053 {
2054 if (num2 >= 9)
2055 {
2056 num = n.DivByULong(s_rgulShiftBase[8]);
2057 num3 = s_rgulShiftBase[8];
2058 num2 -= 9;
2059 }
2060 else
2061 {
2062 num = n.DivByULong(s_rgulShiftBase[num2 - 1]);
2063 num3 = s_rgulShiftBase[num2 - 1];
2064 num2 = 0;
2065 }
2066 }
2067 if (num3 > 1)
2068 {
2069 num /= num3 / 10;
2070 }
2071 if (n.FZero() && (fTruncate || num < 5))
2072 {
2073 n.SetPositive();
2074 return n;
2075 }
2076 if (num >= 5 && !fTruncate)
2077 {
2078 n.AddULong(1u);
2079 }
2080 num2 = Math.Abs(lPosition - n._bScale);
2081 while (num2-- > 0)
2082 {
2083 n.MultByULong(10u);
2084 }
2085 return n;
2086 }
2087
2088 public static SqlDecimal Round(SqlDecimal n, int position)
2089 {
2090 return Round(n, position, fTruncate: false);
2091 }
2092
2093 public static SqlDecimal Truncate(SqlDecimal n, int position)
2094 {
2095 return Round(n, position, fTruncate: true);
2096 }
2097
2098 public static SqlDecimal Power(SqlDecimal n, double exp)
2099 {
2100 if (n.IsNull)
2101 {
2102 return Null;
2103 }
2104 int scale = n.Scale;
2105 double x = n.ToDouble();
2106 n = new SqlDecimal(Math.Pow(x, exp));
2107 n.AdjustScale(scale - n.Scale, fRound: true);
2109 return n;
2110 }
2111
2112 public int CompareTo(object? value)
2113 {
2115 {
2116 return CompareTo(value2);
2117 }
2118 throw ADP.WrongType(value.GetType(), typeof(SqlDecimal));
2119 }
2120
2122 {
2123 if (IsNull)
2124 {
2125 if (!value.IsNull)
2126 {
2127 return -1;
2128 }
2129 return 0;
2130 }
2131 if (value.IsNull)
2132 {
2133 return 1;
2134 }
2135 if (this < value)
2136 {
2137 return -1;
2138 }
2139 if (this > value)
2140 {
2141 return 1;
2142 }
2143 return 0;
2144 }
2145
2146 public override bool Equals([NotNullWhen(true)] object? value)
2147 {
2149 {
2150 return false;
2151 }
2152 if (sqlDecimal.IsNull || IsNull)
2153 {
2154 if (sqlDecimal.IsNull)
2155 {
2156 return IsNull;
2157 }
2158 return false;
2159 }
2160 return (this == sqlDecimal).Value;
2161 }
2162
2163 public override int GetHashCode()
2164 {
2165 if (IsNull)
2166 {
2167 return 0;
2168 }
2169 SqlDecimal sqlDecimal = this;
2170 int num = sqlDecimal.CalculatePrecision();
2171 sqlDecimal.AdjustScale(38 - num, fRound: true);
2172 int bLen = sqlDecimal._bLen;
2173 int num2 = 0;
2174 int[] data = sqlDecimal.Data;
2175 for (int i = 0; i < bLen; i++)
2176 {
2177 int num3 = (num2 >> 28) & 0xFF;
2178 num2 <<= 4;
2179 num2 = num2 ^ data[i] ^ num3;
2180 }
2181 return num2;
2182 }
2183
2185 {
2186 return null;
2187 }
2188
2190 {
2191 string attribute = reader.GetAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance");
2192 if (attribute != null && XmlConvert.ToBoolean(attribute))
2193 {
2194 reader.ReadElementString();
2195 _bStatus = (byte)(0xFEu & _bStatus);
2196 return;
2197 }
2199 _bStatus = sqlDecimal._bStatus;
2200 _bLen = sqlDecimal._bLen;
2201 _bPrec = sqlDecimal._bPrec;
2202 _bScale = sqlDecimal._bScale;
2203 _data1 = sqlDecimal._data1;
2204 _data2 = sqlDecimal._data2;
2205 _data3 = sqlDecimal._data3;
2206 _data4 = sqlDecimal._data4;
2207 }
2208
2210 {
2211 if (IsNull)
2212 {
2213 writer.WriteAttributeString("xsi", "nil", "http://www.w3.org/2001/XMLSchema-instance", "true");
2214 }
2215 else
2216 {
2217 writer.WriteString(ToString());
2218 }
2219 }
2220
2222 {
2223 return new XmlQualifiedName("decimal", "http://www.w3.org/2001/XMLSchema");
2224 }
2225}
static Exception WrongType(Type got, Type expected)
Definition ADP.cs:174
static string ConversionOverflowMessage
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static double Pow(double x, double y)
static double Abs(double value)
static double Floor(double d)
static byte Max(byte val1, byte val2)
Definition Math.cs:738
static bool ToBoolean(string s)
string? GetAttribute(string name)
virtual string ReadElementString()
Definition XmlReader.cs:667
static readonly SqlBoolean Null
Definition SqlBoolean.cs:21
SqlDecimal(ReadOnlySpan< uint > rglData, byte bLen, byte bPrec, byte bScale, bool fPositive)
static SqlDecimal Power(SqlDecimal n, double exp)
static readonly uint[] s_decimalHelpersLo
Definition SqlDecimal.cs:34
static SqlBoolean Equals(SqlDecimal x, SqlDecimal y)
uint DivByULong(uint iDivisor)
static ulong DWL(uint lo, uint hi)
static readonly uint[] s_decimalHelpersHiHi
Definition SqlDecimal.cs:58
static SqlBoolean GreaterThan(SqlDecimal x, SqlDecimal y)
static void MpMove(ReadOnlySpan< uint > rgulS, int ciulS, Span< uint > rgulD, out int ciulD)
static SqlDecimal operator/(SqlDecimal x, SqlDecimal y)
static SqlDecimal Round(SqlDecimal n, int lPosition, bool fTruncate)
static SqlDecimal Floor(SqlDecimal n)
static SqlBoolean operator!=(SqlDecimal x, SqlDecimal y)
int LAbsCmp(SqlDecimal snumOp)
static SqlBoolean LessThanOrEqual(SqlDecimal x, SqlDecimal y)
static readonly uint[] s_decimalHelpersMid
Definition SqlDecimal.cs:42
int CompareTo(SqlDecimal value)
static SqlBoolean operator<=(SqlDecimal x, SqlDecimal y)
static SqlDecimal Parse(string s)
static char ChFromDigit(uint uiDigit)
static byte BGetPrecUI4(uint value)
static SqlDecimal operator*(SqlDecimal x, SqlDecimal y)
static void MpSet(Span< uint > rgulD, out int ciulD, uint iulN)
SqlDecimal(byte bPrecision, byte bScale, bool fPositive, int[] bits)
static SqlBoolean operator>(SqlDecimal x, SqlDecimal y)
static SqlDecimal Truncate(SqlDecimal n, int position)
static SqlDecimal AdjustScale(SqlDecimal n, int digits, bool fRound)
static SqlBoolean operator<(SqlDecimal x, SqlDecimal y)
static SqlInt32 Sign(SqlDecimal n)
static readonly uint[] s_decimalHelpersHi
Definition SqlDecimal.cs:50
static SqlDecimal operator+(SqlDecimal x, SqlDecimal y)
static SqlBoolean operator>=(SqlDecimal x, SqlDecimal y)
static SqlBoolean LessThan(SqlDecimal x, SqlDecimal y)
static ReadOnlySpan< byte > RgCLenFromPrec
static readonly SqlDecimal Null
Definition SqlDecimal.cs:66
static void CheckValidPrecScale(int iPrec, int iScale)
static SqlDecimal Round(SqlDecimal n, int position)
static SqlDecimal ConvertToPrecScale(SqlDecimal n, int precision, int scale)
static XmlQualifiedName GetXsdType(XmlSchemaSet schemaSet)
override bool Equals([NotNullWhen(true)] object? value)
static void MpDiv(ReadOnlySpan< uint > rgulU, int ciulU, Span< uint > rgulD, int ciulD, Span< uint > rgulQ, out int ciulQ, Span< uint > rgulR, out int ciulR)
static readonly byte MaxScale
Definition SqlDecimal.cs:30
static SqlDecimal Add(SqlDecimal x, SqlDecimal y)
static readonly byte MaxPrecision
Definition SqlDecimal.cs:28
void AdjustScale(int digits, bool fRound)
static SqlDecimal Abs(SqlDecimal n)
static SqlDecimal Subtract(SqlDecimal x, SqlDecimal y)
static SqlDecimal Multiply(SqlDecimal x, SqlDecimal y)
void MultByULong(uint uiMultiplier)
static readonly SqlDecimal MinValue
Definition SqlDecimal.cs:68
static readonly uint[] s_rgulShiftBase
Definition SqlDecimal.cs:32
static void CheckValidPrecScale(byte bPrec, byte bScale)
static void MpDiv1(Span< uint > rgulU, ref int ciulU, uint iulD, out uint iulR)
static byte BGetPrecUI8(ulong dwlVal)
static SqlBoolean operator==(SqlDecimal x, SqlDecimal y)
bool VerifyPrecision(byte precision)
static SqlDecimal Divide(SqlDecimal x, SqlDecimal y)
static SqlBoolean NotEquals(SqlDecimal x, SqlDecimal y)
void SetSignBit(bool fPositive)
static SqlDecimal operator-(SqlDecimal x)
static byte CLenFromPrec(byte bPrec)
bool FGt10_38(Span< uint > rglData)
static void MpMul1(Span< uint > piulD, ref int ciulD, uint iulX)
static void ZeroToMaxLen(Span< uint > rgulData, int cUI4sCur)
static void MpNormalize(ReadOnlySpan< uint > rgulU, ref int ciulU)
static SqlDecimal Ceiling(SqlDecimal n)
void MakeInteger(out bool fFraction)
void StoreFromWorkingArray(ReadOnlySpan< uint > rguiData)
static readonly SqlDecimal MaxValue
Definition SqlDecimal.cs:70
SqlDecimal(byte bPrecision, byte bScale, bool fPositive, int data1, int data2, int data3, int data4)
EComparison CompareNm(SqlDecimal snumOp)
static SqlBoolean GreaterThanOrEqual(SqlDecimal x, SqlDecimal y)
static readonly SqlInt32 Null
Definition SqlInt32.cs:19
static readonly SqlInt32 Zero
Definition SqlInt32.cs:21
unsafe void Clear()
Definition Span.cs:198