[sgen] Clear the card table in the finishing pause
[mono.git] / mcs / class / corlib / Test / System / DecimalTest.cs
1 // DecimalTest.cs - NUnit Test Cases for the System.Decimal struct
2 //
3 // Authors:
4 //      Martin Weindel (martin.weindel@t-online.de)
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // (C) Martin Weindel, 2001
8 // Copyright (C) 2004 Novell (http://www.novell.com)
9 // 
10
11 using NUnit.Framework;
12 using System;
13
14 using System.Globalization;
15 using System.Runtime.CompilerServices;
16 using System.Threading;
17
18 namespace MonoTests.System
19 {
20         internal struct ParseTest
21         {
22                 public ParseTest (String str, bool exceptionFlag)
23                 {
24                         this.str = str;
25                         this.exceptionFlag = exceptionFlag;
26                         this.style = NumberStyles.Number;
27                         this.d = 0;
28                 }
29
30                 public ParseTest (String str, Decimal d)
31                 {
32                         this.str = str;
33                         this.exceptionFlag = false;
34                         this.style = NumberStyles.Number;
35                         this.d = d;
36                 }
37
38                 public ParseTest (String str, Decimal d, NumberStyles style)
39                 {
40                         this.str = str;
41                         this.exceptionFlag = false;
42                         this.style = style;
43                         this.d = d;
44                 }
45
46                 public String str;
47                 public Decimal d;
48                 public NumberStyles style;
49                 public bool exceptionFlag;
50         }
51
52         internal struct ToStringTest
53         {
54                 public ToStringTest (String format, Decimal d, String str)
55                 {
56                         this.format = format;
57                         this.d = d;
58                         this.str = str;
59                 }
60
61                 public String format;
62                 public Decimal d;
63                 public String str;
64         }
65
66         [TestFixture]
67         public class DecimalTest
68         {
69                 private const int negativeBitValue = unchecked ((int) 0x80000000);
70                 private const int negativeScale4Value = unchecked ((int) 0x80040000);
71                 private int [] parts0 = { 0, 0, 0, 0 }; //Positive Zero.
72                 private int [] parts1 = { 1, 0, 0, 0 };
73                 private int [] parts2 = { 0, 1, 0, 0 };
74                 private int [] parts3 = { 0, 0, 1, 0 };
75                 private int [] parts4 = { 0, 0, 0, negativeBitValue }; // Negative zero.
76                 private int [] parts5 = { 1, 1, 1, 0 };
77                 private int [] partsMaxValue = { -1, -1, -1, 0 };
78                 private int [] partsMinValue = { -1, -1, -1, negativeBitValue };
79                 private int [] parts6 = { 1234, 5678, 8888, negativeScale4Value };
80                 private NumberFormatInfo NfiUser, NfiBroken;
81
82                 private CultureInfo old_culture;
83
84                 [TestFixtureSetUp]
85                 public void FixtureSetUp ()
86                 {
87                         old_culture = Thread.CurrentThread.CurrentCulture;
88
89                         // Set culture to en-US and don't let the user override.
90                         Thread.CurrentThread.CurrentCulture = new CultureInfo ("en-US", false);
91
92                         NfiUser = new NumberFormatInfo ();
93                         NfiUser.CurrencyDecimalDigits = 3;
94                         NfiUser.CurrencyDecimalSeparator = ",";
95                         NfiUser.CurrencyGroupSeparator = "_";
96                         NfiUser.CurrencyGroupSizes = new int [] { 2, 1, 0 };
97                         NfiUser.CurrencyNegativePattern = 10;
98                         NfiUser.CurrencyPositivePattern = 3;
99                         NfiUser.CurrencySymbol = "XYZ";
100                         NfiUser.NumberDecimalSeparator = "##";
101                         NfiUser.NumberDecimalDigits = 4;
102                         NfiUser.NumberGroupSeparator = "__";
103                         NfiUser.NumberGroupSizes = new int [] { 2, 1 };
104                         NfiUser.PercentDecimalDigits = 1;
105                         NfiUser.PercentDecimalSeparator = ";";
106                         NfiUser.PercentGroupSeparator = "~";
107                         NfiUser.PercentGroupSizes = new int [] { 1 };
108                         NfiUser.PercentNegativePattern = 2;
109                         NfiUser.PercentPositivePattern = 2;
110                         NfiUser.PercentSymbol = "%%%";
111
112                         NfiBroken = new NumberFormatInfo ();
113                         NfiBroken.NumberDecimalSeparator = ".";
114                         NfiBroken.NumberGroupSeparator = ".";
115                         NfiBroken.CurrencyDecimalSeparator = ".";
116                         NfiBroken.CurrencyGroupSeparator = ".";
117                 }
118
119                 [TestFixtureTearDown]
120                 public void FixtureTearDown ()
121                 {
122                         Thread.CurrentThread.CurrentCulture = old_culture;
123                 }
124
125                 [Test]
126                 public void TestToString ()
127                 {
128                         ToStringTest [] tab = {
129                                 new ToStringTest ("F", 12.345678m, "12.35"),
130                                 new ToStringTest ("F3", 12.345678m, "12.346"),
131                                 new ToStringTest ("F0", 12.345678m, "12"),
132                                 new ToStringTest ("F7", 12.345678m, "12.3456780"),
133                                 new ToStringTest ("g", 12.345678m, "12.345678"),
134                                 new ToStringTest ("E", 12.345678m, "1.234568E+001"),
135                                 new ToStringTest ("E3", 12.345678m, "1.235E+001"),
136                                 new ToStringTest ("E0", 12.345678m, "1E+001"),
137                                 new ToStringTest ("e8", 12.345678m, "1.23456780e+001"),
138                                 new ToStringTest ("F", 0.0012m, "0.00"),
139                                 new ToStringTest ("F3", 0.0012m, "0.001"),
140                                 new ToStringTest ("F0", 0.0012m, "0"),
141                                 new ToStringTest ("F6", 0.0012m, "0.001200"),
142                                 new ToStringTest ("e", 0.0012m, "1.200000e-003"),
143                                 new ToStringTest ("E3", 0.0012m, "1.200E-003"),
144                                 new ToStringTest ("E0", 0.0012m, "1E-003"),
145                                 new ToStringTest ("E6", 0.0012m, "1.200000E-003"),
146                                 new ToStringTest ("F4", -0.001234m, "-0.0012"),
147                                 new ToStringTest ("E3", -0.001234m, "-1.234E-003"),
148                                 new ToStringTest ("g", -0.000012m, "-0.000012"),
149                                 new ToStringTest ("g0", -0.000012m, "-1.2e-05"),
150                                 new ToStringTest ("g2", -0.000012m, "-1.2e-05"),
151                                 new ToStringTest ("g20", -0.000012m, "-1.2e-05"),
152                                 new ToStringTest ("g", -0.00012m, "-0.00012"),
153                                 new ToStringTest ("g4", -0.00012m, "-0.00012"),
154                                 new ToStringTest ("g7", -0.00012m, "-0.00012"),
155                                 new ToStringTest ("g", -0.0001234m, "-0.0001234"),
156                                 new ToStringTest ("g", -0.0012m, "-0.0012"),
157                                 new ToStringTest ("g", -0.001234m, "-0.001234"),
158                                 new ToStringTest ("g", -0.012m, "-0.012"),
159                                 new ToStringTest ("g4", -0.012m, "-0.012"),
160                                 new ToStringTest ("g", -0.12m, "-0.12"),
161                                 new ToStringTest ("g", -1.2m, "-1.2"),
162                                 new ToStringTest ("g4", -120m, "-120"),
163                                 new ToStringTest ("g", -12.000m, "-12.000"),
164                                 new ToStringTest ("g0", -12.000m, "-12"),
165                                 new ToStringTest ("g6", -12.000m, "-12"),
166                                 new ToStringTest ("g", -12m, "-12"),
167                                 new ToStringTest ("g", -120m, "-120"),
168                                 new ToStringTest ("g", -1200m, "-1200"),
169                                 new ToStringTest ("g4", -1200m, "-1200"),
170                                 new ToStringTest ("g", -1234m, "-1234"),
171                                 new ToStringTest ("g", -12000m, "-12000"),
172                                 new ToStringTest ("g4", -12000m, "-1.2e+04"),
173                                 new ToStringTest ("g5", -12000m, "-12000"),
174                                 new ToStringTest ("g", -12345m, "-12345"),
175                                 new ToStringTest ("g", -120000m, "-120000"),
176                                 new ToStringTest ("g4", -120000m, "-1.2e+05"),
177                                 new ToStringTest ("g5", -120000m, "-1.2e+05"),
178                                 new ToStringTest ("g6", -120000m, "-120000"),
179                                 new ToStringTest ("g", -123456.1m, "-123456.1"),
180                                 new ToStringTest ("g5", -123456.1m, "-1.2346e+05"),
181                                 new ToStringTest ("g6", -123456.1m, "-123456"),
182                                 new ToStringTest ("g", -1200000m, "-1200000"),
183                                 new ToStringTest ("g", -123456.1m, "-123456.1"),
184                                 new ToStringTest ("g", -123456.1m, "-123456.1"),
185                                 new ToStringTest ("g", -1234567.1m, "-1234567.1"),
186                                 new ToStringTest ("g", -12000000m, "-12000000"),
187                                 new ToStringTest ("g", -12345678.1m, "-12345678.1"),
188                                 new ToStringTest ("g", -12000000000000000000m, "-12000000000000000000"),
189                                 new ToStringTest ("F", -123, "-123.00"),
190                                 new ToStringTest ("F3", -123, "-123.000"),
191                                 new ToStringTest ("F0", -123, "-123"),
192                                 new ToStringTest ("E3", -123, "-1.230E+002"),
193                                 new ToStringTest ("E0", -123, "-1E+002"),
194                                 new ToStringTest ("E", -123, "-1.230000E+002"),
195                                 new ToStringTest ("F3", Decimal.MinValue, "-79228162514264337593543950335.000"),
196                                 new ToStringTest ("F", Decimal.MinValue, "-79228162514264337593543950335.00"),
197                                 new ToStringTest ("F0", Decimal.MinValue, "-79228162514264337593543950335"),
198                                 new ToStringTest ("E", Decimal.MinValue, "-7.922816E+028"),
199                                 new ToStringTest ("E3", Decimal.MinValue, "-7.923E+028"),
200                                 new ToStringTest ("E28", Decimal.MinValue, "-7.9228162514264337593543950335E+028"),
201                                 new ToStringTest ("E30", Decimal.MinValue, "-7.922816251426433759354395033500E+028"),
202                                 new ToStringTest ("E0", Decimal.MinValue, "-8E+028"),
203                                 new ToStringTest ("N3", Decimal.MinValue, "-79,228,162,514,264,337,593,543,950,335.000"),
204                                 new ToStringTest ("N0", Decimal.MinValue, "-79,228,162,514,264,337,593,543,950,335"),
205                                 new ToStringTest ("N", Decimal.MinValue, "-79,228,162,514,264,337,593,543,950,335.00"),
206                                 new ToStringTest ("n3", Decimal.MinValue, "-79,228,162,514,264,337,593,543,950,335.000"),
207                                 new ToStringTest ("n0", Decimal.MinValue, "-79,228,162,514,264,337,593,543,950,335"),
208                                 new ToStringTest ("n", Decimal.MinValue, "-79,228,162,514,264,337,593,543,950,335.00"),
209                                 new ToStringTest ("C", 123456.7890m, NumberFormatInfo.InvariantInfo.CurrencySymbol + "123,456.79"),
210                                 new ToStringTest ("C", -123456.7890m, "(" + NumberFormatInfo.InvariantInfo.CurrencySymbol + "123,456.79)"),
211                                 new ToStringTest ("C3", 1123456.7890m, NumberFormatInfo.InvariantInfo.CurrencySymbol + "1,123,456.789"),
212                                 new ToStringTest ("P", 123456.7891m, "12,345,678.91 %"),
213                                 new ToStringTest ("P", -123456.7892m, "-12,345,678.92 %"),
214                                 new ToStringTest ("P3", 1234.56789m, "123,456.789 %"),
215                         };
216
217                         NumberFormatInfo nfi = NumberFormatInfo.InvariantInfo;
218
219                         for (int i = 0; i < tab.Length; i++) {
220                                 try {
221                                         string s = tab [i].d.ToString (tab [i].format, nfi);
222                                         Assert.AreEqual (tab [i].str, s, "A01 tab[" + i + "].format = '" + tab [i].format + "')");
223                                 } catch (OverflowException) {
224                                         Assert.Fail (tab [i].d.ToString (tab [i].format, nfi) + " (format = '" + tab [i].format + "'): unexpected exception !");
225                                 } catch (NUnit.Framework.AssertionException e) {
226                                         throw e;
227                                 } catch (Exception e) {
228                                         Assert.Fail ("Unexpected Exception when i = " + i + ". e = " + e);
229                                 }
230                         }
231                 }
232
233                 [Test]
234                 public void TestCurrencyPattern ()
235                 {
236                         NumberFormatInfo nfi2 = (NumberFormatInfo) NfiUser.Clone ();
237                         Decimal d = -1234567.8976m;
238                         string [] ergCurrencyNegativePattern = new String [16] {
239                                 "(XYZ1234_5_67,898)", "-XYZ1234_5_67,898", "XYZ-1234_5_67,898", "XYZ1234_5_67,898-",
240                                 "(1234_5_67,898XYZ)", "-1234_5_67,898XYZ", "1234_5_67,898-XYZ", "1234_5_67,898XYZ-",
241                                 "-1234_5_67,898 XYZ", "-XYZ 1234_5_67,898", "1234_5_67,898 XYZ-", "XYZ 1234_5_67,898-",
242                                 "XYZ -1234_5_67,898", "1234_5_67,898- XYZ", "(XYZ 1234_5_67,898)", "(1234_5_67,898 XYZ)",
243                         };
244
245                         for (int i = 0; i < ergCurrencyNegativePattern.Length; i++) {
246                                 nfi2.CurrencyNegativePattern = i;
247                                 if (d.ToString ("C", nfi2) != ergCurrencyNegativePattern [i]) {
248                                         Assert.Fail ("CurrencyNegativePattern #" + i + " failed: " +
249                                                 d.ToString ("C", nfi2) + " != " + ergCurrencyNegativePattern [i]);
250                                 }
251                         }
252
253                         d = 1234567.8976m;
254                         string [] ergCurrencyPositivePattern = new String [4] {
255                                 "XYZ1234_5_67,898", "1234_5_67,898XYZ", "XYZ 1234_5_67,898", "1234_5_67,898 XYZ",
256                         };
257
258                         for (int i = 0; i < ergCurrencyPositivePattern.Length; i++) {
259                                 nfi2.CurrencyPositivePattern = i;
260                                 if (d.ToString ("C", nfi2) != ergCurrencyPositivePattern [i]) {
261                                         Assert.Fail ("CurrencyPositivePattern #" + i + " failed: " +
262                                                 d.ToString ("C", nfi2) + " != " + ergCurrencyPositivePattern [i]);
263                                 }
264                         }
265                 }
266
267                 [Test]
268                 public void TestNumberNegativePattern ()
269                 {
270                         NumberFormatInfo nfi2 = (NumberFormatInfo) NfiUser.Clone ();
271                         Decimal d = -1234.89765m;
272                         string [] ergNumberNegativePattern = new String [5] {
273                                 "(1__2__34##8977)", "-1__2__34##8977", "- 1__2__34##8977", "1__2__34##8977-", "1__2__34##8977 -",
274                         };
275
276                         for (int i = 0; i < ergNumberNegativePattern.Length; i++) {
277                                 nfi2.NumberNegativePattern = i;
278                                 Assert.AreEqual (ergNumberNegativePattern [i], d.ToString ("N", nfi2), "NumberNegativePattern #" + i);
279                         }
280                 }
281
282                 [Test]
283                 public void TestBrokenNFI ()
284                 {
285                         Assert.AreEqual (5.3m, decimal.Parse ("5.3", NumberStyles.Number, NfiBroken), "Parsing with broken NFI");
286                 }
287                 
288                 [Test]
289                 public void TestPercentPattern ()
290                 {
291                         NumberFormatInfo nfi2 = (NumberFormatInfo) NfiUser.Clone ();
292                         Decimal d = -1234.8976m;
293                         string [] ergPercentNegativePattern = new String [3] {
294                                 "-1~2~3~4~8~9;8 %%%", "-1~2~3~4~8~9;8%%%", "-%%%1~2~3~4~8~9;8"
295                         };
296
297                         for (int i = 0; i < ergPercentNegativePattern.Length; i++) {
298                                 nfi2.PercentNegativePattern = i;
299                                 if (d.ToString ("P", nfi2) != ergPercentNegativePattern [i]) {
300                                         Assert.Fail ("PercentNegativePattern #" + i + " failed: " +
301                                                 d.ToString ("P", nfi2) + " != " + ergPercentNegativePattern [i]);
302                                 }
303                         }
304
305                         d = 1234.8976m;
306                         string [] ergPercentPositivePattern = new String [3] {
307                                 "1~2~3~4~8~9;8 %%%", "1~2~3~4~8~9;8%%%", "%%%1~2~3~4~8~9;8"
308                         };
309
310                         for (int i = 0; i < ergPercentPositivePattern.Length; i++) {
311                                 nfi2.PercentPositivePattern = i;
312                                 if (d.ToString ("P", nfi2) != ergPercentPositivePattern [i]) {
313                                         Assert.Fail ("PercentPositivePattern #" + i + " failed: " +
314                                                 d.ToString ("P", nfi2) + " != " + ergPercentPositivePattern [i]);
315                                 }
316                         }
317                 }
318
319                 ParseTest [] tab = {
320                                 new ParseTest("1.2345", 1.2345m),
321                                 new ParseTest("1.2345\0", 1.2345m),
322                                 new ParseTest("1.2345\0\0\0\0", 1.2345m),
323                                 new ParseTest("-9876543210", -9876543210m),
324                                 new ParseTest(NumberFormatInfo.InvariantInfo.CurrencySymbol 
325                                         + " (  79,228,162,514,264,337,593,543,950,335.000 ) ", 
326                                         Decimal.MinValue, NumberStyles.Currency),
327                                 new ParseTest("1.234567890e-10", (Decimal)1.234567890e-10, NumberStyles.Float),
328                                 new ParseTest("1.234567890e-24", 1.2346e-24m, NumberStyles.Float),
329                                 new ParseTest("  47896396.457983645462346E10  ", 478963964579836454.62346m, NumberStyles.Float),
330                                 new ParseTest("-7922816251426433759354395033.250000000000001", -7922816251426433759354395033.3m),
331                                 new ParseTest("-00000000000000795033.2500000000000000", -795033.25m),
332                                 new ParseTest("-000000000000001922816251426433759354395033.300000000000000", -1922816251426433759354395033.3m),
333                                 new ParseTest("-7922816251426433759354395033.150000000000", -7922816251426433759354395033.2m),
334                                 new ParseTest("-7922816251426433759354395033.2400000000000", -7922816251426433759354395033.2m),
335                                 new ParseTest("-7922816251426433759354395033.2600000000000", -7922816251426433759354395033.3m),
336                                 new ParseTest("987654321098765432109876543.25999", 987654321098765432109876543.3m, NumberStyles.Float),
337                                 new ParseTest("987654321098765432109876543.25199", 987654321098765432109876543.3m, NumberStyles.Float),
338                                 new ParseTest("2.22222222222222222222222222225", 2.2222222222222222222222222222m, NumberStyles.Float)
339                 };
340
341                 [Test]
342                 public void TestParse ()
343                 {
344
345                         Decimal d;
346                         for (int i = 0; i < tab.Length; i++) {
347                                 try {
348                                         d = Decimal.Parse (tab [i].str, tab [i].style, NumberFormatInfo.InvariantInfo);
349                                         if (tab [i].exceptionFlag) {
350                                                 Assert.Fail (tab [i].str + ": missing exception !");
351                                         } else if (d != tab [i].d) {
352                                                 Assert.Fail (tab [i].str + " != " + d);
353                                         }
354                                 } catch (OverflowException) {
355                                         if (!tab [i].exceptionFlag) {
356                                                 Assert.Fail (tab [i].str + ": unexpected exception !");
357                                         }
358                                 }
359                         }
360
361                         try {
362                                 d = Decimal.Parse (null);
363                                 Assert.Fail ("Expected ArgumentNullException");
364                         } catch (ArgumentNullException) {
365                                 //ok
366                         }
367
368                         try {
369                                 d = Decimal.Parse ("123nx");
370                                 Assert.Fail ("Expected FormatException");
371                         } catch (FormatException) {
372                                 //ok
373                         }
374
375                         try {
376                                 d = Decimal.Parse ("79228162514264337593543950336");
377                                 Assert.Fail ("Expected OverflowException" + d);
378                         } catch (OverflowException) {
379                                 //ok
380                         }
381
382                         try {
383                                 d = Decimal.Parse ("5\05");
384                                 Assert.Fail ("Expected FormatException" + d);
385                         } catch (FormatException) {
386                                 //ok
387                         }
388                 }
389
390                 [Test]
391                 public void TestConstants ()
392                 {
393                         Assert.AreEqual (0m, Decimal.Zero, "Zero");
394                         Assert.AreEqual (1m, Decimal.One, "One");
395                         Assert.AreEqual (-1m, Decimal.MinusOne, "MinusOne");
396                         Assert.AreEqual (79228162514264337593543950335m, Decimal.MaxValue, "MaxValue");
397                         Assert.AreEqual (-79228162514264337593543950335m, Decimal.MinValue, "MinValue");
398                         Assert.IsTrue (-1m == Decimal.MinusOne, "MinusOne 2");
399                 }
400
401                 [Test]
402                 public void TestConstructInt32 ()
403                 {
404                         decimal [] dtab = { 0m, 1m, -1m, 123456m, -1234567m };
405                         int [] itab = { 0, 1, -1, 123456, -1234567 };
406
407                         Decimal d;
408
409                         for (int i = 0; i < dtab.GetLength (0); i++) {
410                                 d = new Decimal (itab [i]);
411                                 if ((decimal) d != dtab [i]) {
412                                         Assert.Fail ("Int32 -> Decimal: " + itab [i] + " != " + d);
413                                 } else {
414                                         int n = (int) d;
415                                         if (n != itab [i]) {
416                                                 Assert.Fail ("Decimal -> Int32: " + d + " != " + itab [i]);
417                                         }
418                                 }
419                         }
420
421                         d = new Decimal (Int32.MaxValue);
422                         Assert.IsTrue ((int) d == Int32.MaxValue);
423
424                         d = new Decimal (Int32.MinValue);
425                         Assert.IsTrue ((int) d == Int32.MinValue);
426                 }
427
428                 [Test]
429                 public void TestConstructUInt32 ()
430                 {
431                         decimal [] dtab = { 0m, 1m, 123456m, 123456789m };
432                         uint [] itab = { 0, 1, 123456, 123456789 };
433
434                         Decimal d;
435
436                         for (int i = 0; i < dtab.GetLength (0); i++) {
437                                 d = new Decimal (itab [i]);
438                                 if ((decimal) d != dtab [i]) {
439                                         Assert.Fail ("UInt32 -> Decimal: " + itab [i] + " != " + d);
440                                 } else {
441                                         uint n = (uint) d;
442                                         if (n != itab [i]) {
443                                                 Assert.Fail ("Decimal -> UInt32: " + d + " != " + itab [i]);
444                                         }
445                                 }
446                         }
447
448                         d = new Decimal (UInt32.MaxValue);
449                         Assert.IsTrue ((uint) d == UInt32.MaxValue);
450
451                         d = new Decimal (UInt32.MinValue);
452                         Assert.IsTrue ((uint) d == UInt32.MinValue);
453                 }
454
455                 [Test]
456                 public void TestConstructInt64 ()
457                 {
458                         decimal [] dtab = { 0m, 1m, -1m, 9876543m, -9876543210m, 12345678987654321m };
459                         long [] itab = { 0, 1, -1, 9876543, -9876543210L, 12345678987654321L };
460
461                         Decimal d;
462
463                         for (int i = 0; i < dtab.GetLength (0); i++) {
464                                 d = new Decimal (itab [i]);
465                                 if ((decimal) d != dtab [i]) {
466                                         Assert.Fail ("Int64 -> Decimal: " + itab [i] + " != " + d);
467                                 } else {
468                                         long n = (long) d;
469                                         if (n != itab [i]) {
470                                                 Assert.Fail ("Decimal -> Int64: " + d + " != " + itab [i]);
471                                         }
472                                 }
473                         }
474
475                         d = new Decimal (Int64.MaxValue);
476                         Assert.IsTrue ((long) d == Int64.MaxValue);
477
478                         d = new Decimal (Int64.MinValue);
479                         Assert.IsTrue ((long) d == Int64.MinValue);
480                 }
481
482                 [Test]
483                 public void TestConstructUInt64 ()
484                 {
485                         decimal [] dtab = { 0m, 1m, 987654321m, 123456789876543210m };
486                         ulong [] itab = { 0, 1, 987654321, 123456789876543210L };
487
488                         Decimal d;
489
490                         for (int i = 0; i < dtab.GetLength (0); i++) {
491                                 d = new Decimal (itab [i]);
492                                 if ((decimal) d != dtab [i]) {
493                                         Assert.Fail ("UInt64 -> Decimal: " + itab [i] + " != " + d);
494                                 } else {
495                                         ulong n = (ulong) d;
496                                         if (n != itab [i]) {
497                                                 Assert.Fail ("Decimal -> UInt64: " + d + " != " + itab [i]);
498                                         }
499                                 }
500                         }
501
502                         d = new Decimal (UInt64.MaxValue);
503                         Assert.IsTrue ((ulong) d == UInt64.MaxValue);
504
505                         d = new Decimal (UInt64.MinValue);
506                         Assert.IsTrue ((ulong) d == UInt64.MinValue);
507                 }
508
509                 [Test]
510                 public void TestConstructSingle ()
511                 {
512                         Decimal d;
513
514                         d = new Decimal (-1.2345678f);
515                         Assert.AreEqual (-1.234568m, (decimal) d, "A#01");
516
517                         d = 3;
518                         Assert.AreEqual (3.0f, (float) d, "A#02");
519
520                         d = new Decimal (0.0f);
521                         Assert.AreEqual (0m, (decimal) d, "A#03");
522                         Assert.AreEqual (0.0f, (float) d, "A#04");
523
524                         d = new Decimal (1.0f);
525                         Assert.AreEqual (1m, (decimal) d, "A#05");
526                         Assert.AreEqual (1.0f, (float) d, "A#06");
527
528                         d = new Decimal (-1.2345678f);
529                         Assert.AreEqual (-1.234568m, (decimal) d, "A#07");
530                         Assert.AreEqual (-1.234568f, (float) d, "A#08");
531
532                         d = new Decimal (1.2345673f);
533                         Assert.AreEqual (1.234567m, (decimal) d, "A#09");
534
535                         d = new Decimal (1.2345673e7f);
536                         Assert.AreEqual (12345670m, (decimal) d, "A#10");
537
538                         d = new Decimal (1.2345673e-17f);
539                         Assert.AreEqual (0.00000000000000001234567m, (decimal) d, "A#11");
540                         Assert.AreEqual (1.234567e-17f, (float) d, "A#12");
541
542                         // test exceptions
543                         try {
544                                 d = new Decimal (Single.MaxValue);
545                                 Assert.Fail ();
546                         } catch (OverflowException) {
547                         }
548
549                         try {
550                                 d = new Decimal (Single.NaN);
551                                 Assert.Fail ();
552                         } catch (OverflowException) {
553                         }
554
555                         try {
556                                 d = new Decimal (Single.PositiveInfinity);
557                                 Assert.Fail ();
558                         } catch (OverflowException) {
559                         }
560                 }
561
562                 [Test]
563                 public void TestConstructSingleRounding_NowWorking ()
564                 {
565                         decimal d;
566
567                         d = new Decimal (1765.23454f);
568                         Assert.AreEqual (1765.234m, d, "failed banker's rule rounding test 2");
569
570                         d = new Decimal (0.00017652356f);
571                         Assert.AreEqual (0.0001765236m, d, "06");
572
573                         d = new Decimal (0.000176523554f);
574                         Assert.AreEqual (0.0001765236m, d, "failed banker's rule rounding test 3");
575
576                         d = new Decimal (0.00017652354f);
577                         Assert.AreEqual (0.0001765235m, d, "08");
578
579                         d = new Decimal (0.00017652346f);
580                         Assert.AreEqual (0.0001765235m, d, "09");
581
582                         d = new Decimal (0.000176523454f);
583                         Assert.AreEqual (0.0001765234m, d, "failed banker's rule rounding test 4");
584
585                         d = new Decimal (0.00017652344f);
586                         Assert.AreEqual (0.0001765234m, d, "11");
587                 }
588
589                 public void TestConstructSingleRounding ()
590                 {
591                         decimal d;
592
593                         d = new Decimal (1765.2356f);
594                         Assert.IsTrue (d == 1765.236m, "01");
595
596                         d = new Decimal (1765.23554f);
597                         Assert.IsTrue (d == 1765.236m, "failed banker's rule rounding test 1");
598
599                         d = new Decimal (1765.2354f);
600                         Assert.IsTrue (d == 1765.235m, "03");
601
602                         d = new Decimal (1765.2346f);
603                         Assert.IsTrue (d == 1765.235m, "04");
604
605                         d = new Decimal (1765.2344f);
606                         Assert.IsTrue (d == 1765.234m, "05");
607
608                         d = new Decimal (3.7652356e10f);
609                         Assert.IsTrue (d == 37652360000m, "12");
610
611                         d = new Decimal (3.7652356e20f);
612                         Assert.IsTrue (d == 376523600000000000000m, "13");
613
614                         d = new Decimal (3.76523554e20f);
615                         Assert.IsTrue (d == 376523600000000000000m, "failed banker's rule rounding test 5");
616
617                         d = new Decimal (3.7652352e20f);
618                         Assert.IsTrue (d == 376523500000000000000m, "15");
619
620                         d = new Decimal (3.7652348e20f);
621                         Assert.IsTrue (d == 376523500000000000000m, "16");
622
623                         d = new Decimal (3.76523454e20f);
624                         Assert.IsTrue (d == 376523400000000000000m, "failed banker's rule rounding test 6");
625
626                         d = new Decimal (3.7652342e20f);
627                         Assert.IsTrue (d == 376523400000000000000m, "18");
628                 }
629
630                 [Test]
631                 [SetCulture("en-US")]
632                 public void TestConstructDouble ()
633                 {
634                         Decimal d;
635
636                         d = new Decimal (0.0);
637                         Assert.IsTrue ((decimal) d == 0m);
638
639                         d = new Decimal (1.0);
640                         Assert.IsTrue ((decimal) d == 1m);
641                         Assert.IsTrue (1.0 == (double) d);
642
643                         d = new Decimal (-1.2345678901234);
644                         Assert.IsTrue ((decimal) d == -1.2345678901234m);
645                         Assert.IsTrue (-1.2345678901234 == (double) d);
646
647                         d = new Decimal (1.2345678901234);
648                         Assert.IsTrue ((decimal) d == 1.2345678901234m);
649
650                         d = new Decimal (1.2345678901234e8);
651                         Assert.IsTrue ((decimal) d == 123456789.01234m);
652                         Assert.IsTrue (1.2345678901234e8 == (double) d);
653
654                         d = new Decimal (1.2345678901234e16);
655                         Assert.IsTrue ((decimal) d == 12345678901234000m);
656                         Assert.IsTrue (1.2345678901234e16 == (double) d);
657
658                         d = new Decimal (1.2345678901234e24);
659                         Assert.IsTrue ((decimal) d == 1234567890123400000000000m);
660                         Assert.IsTrue (1.2345678901234e24 == (double) d);
661
662                         d = new Decimal (1.2345678901234e28);
663                         Assert.IsTrue ((decimal) d == 1.2345678901234e28m);
664                         Assert.IsTrue (1.2345678901234e28 == (double) d);
665
666                         d = new Decimal (7.2345678901234e28);
667                         Assert.IsTrue ((decimal) d == 7.2345678901234e28m);
668                         Assert.IsTrue (new Decimal ((double) d) == d);
669
670                         d = new Decimal (1.2345678901234e-8);
671                         Assert.IsTrue ((decimal) d == 1.2345678901234e-8m);
672
673                         d = new Decimal (1.2345678901234e-14);
674                         Assert.IsTrue ((decimal) d == 1.2345678901234e-14m);
675                         Assert.IsTrue (1.2345678901234e-14 == (double) d);
676
677                         d = new Decimal (1.2342278901234e-25);
678                         Assert.AreEqual (d, 1.234e-25m, "A10");
679
680                         //
681                         // Make sure that 0.6 is turned into
682                         // the 96 bit value 6 with the magnitude set to
683                         //
684                         double mydouble = 0.6;
685                         d = new Decimal (mydouble);
686                         int [] bits = Decimal.GetBits (d);
687                         Assert.AreEqual (bits [0], 6, "f1");
688                         Assert.AreEqual (bits [1], 0, "f2");
689                         Assert.AreEqual (bits [2], 0, "f3");
690                         Assert.AreEqual (bits [3], 65536, "f4");
691
692                         //
693                         // Make sure that we properly parse this value
694                         // this in particular exposes a bug in the
695                         // unmanaged version which rounds to 1234 instead
696                         // of 1235, here to make sure we do not regress
697                         // on the future.
698                         //
699                         mydouble = 1.2345679329684657e-25;
700                         d = new Decimal (mydouble);
701                         Assert.AreEqual (d.ToString (), "0.0000000000000000000000001235", "f5");
702                         
703                         // test exceptions
704                         try {
705                                 d = new Decimal (8e28);
706                                 Assert.Fail ();
707                         } catch (OverflowException) {
708                         }
709
710                         try {
711                                 d = new Decimal (8e48);
712                                 Assert.Fail ();
713                         } catch (OverflowException) {
714                         }
715
716                         try {
717                                 d = new Decimal (Double.NaN);
718                                 Assert.Fail ();
719                         } catch (OverflowException) {
720                         }
721
722                         try {
723                                 d = new Decimal (Double.PositiveInfinity);
724                                 Assert.Fail ();
725                         } catch (OverflowException) {
726                         }
727                 }
728
729                 [Test]
730                 public void TestConstructDoubleRound ()
731                 {
732                         decimal d;
733                         int TestNum = 1;
734
735                         try {
736                                 d = new Decimal (1765.231234567857);
737                                 Assert.AreEqual (1765.23123456786m, d, "A01");
738
739                                 TestNum++;
740                                 d = new Decimal (1765.2312345678554);
741                                 Assert.AreEqual (1765.23123456786m, d, "A02, failed banker's rule rounding test 1");
742                                 Assert.AreEqual (1765.23123456786, (double) d, "A03");
743
744                                 TestNum++;
745                                 d = new Decimal (1765.231234567853);
746                                 Assert.IsTrue (d == 1765.23123456785m);
747
748                                 TestNum++;
749                                 d = new Decimal (1765.231234567847);
750                                 Assert.IsTrue (d == 1765.23123456785m);
751
752                                 TestNum++;
753                                 d = new Decimal (1765.231234567843);
754                                 Assert.IsTrue (d == 1765.23123456784m);
755
756                                 TestNum++;
757                                 d = new Decimal (1.765231234567857e-9);
758                                 Assert.IsTrue (d == 1.76523123456786e-9m);
759
760                                 TestNum++;
761                                 d = new Decimal (1.7652312345678554e-9);
762                                 Assert.IsTrue (d == 1.76523123456786e-9m, "failed banker's rule rounding test 3");
763
764                                 TestNum++;
765                                 d = new Decimal (1.765231234567853e-9);
766                                 Assert.IsTrue (d == 1.76523123456785e-9m);
767
768                                 TestNum++;
769                                 d = new Decimal (1.765231234567857e+24);
770                                 Assert.IsTrue (d == 1.76523123456786e+24m);
771
772                                 TestNum++;
773                                 d = new Decimal (1.7652312345678554e+24);
774                                 Assert.IsTrue (d == 1.76523123456786e+24m, "failed banker's rule rounding test 4");
775
776                                 TestNum++;
777                                 d = new Decimal (1.765231234567853e+24);
778                                 Assert.IsTrue (d == 1.76523123456785e+24m);
779
780                                 TestNum++;
781                                 d = new Decimal (1765.2312345678454);
782                                 Assert.IsTrue (d == 1765.23123456785m);
783                         } catch (Exception e) {
784                                 Assert.Fail ("At TestNum = " + TestNum + " unexpected exception. e = " + e);
785                         }
786                 }
787
788                 [Test]
789                 public void TestNegate ()
790                 {
791                         decimal d;
792
793                         d = new Decimal (12345678);
794                         Assert.IsTrue ((decimal) Decimal.Negate (d) == -12345678m);
795                 }
796
797                 [Test]
798                 public void TestPartConstruct ()
799                 {
800                         decimal d;
801
802                         d = new Decimal (parts0);
803                         Assert.IsTrue (d == 0);
804
805                         d = new Decimal (parts1);
806                         Assert.IsTrue (d == 1);
807
808                         d = new Decimal (parts2);
809                         Assert.IsTrue (d == 4294967296m);
810
811                         d = new Decimal (parts3);
812                         Assert.IsTrue (d == 18446744073709551616m);
813
814                         d = new Decimal (parts4);
815                         Assert.IsTrue (d == 0m);
816
817                         d = new Decimal (parts5);
818                         Assert.IsTrue (d == 18446744078004518913m);
819
820                         d = new Decimal (partsMaxValue);
821                         Assert.IsTrue (d == Decimal.MaxValue);
822
823                         d = new Decimal (partsMinValue);
824                         Assert.IsTrue (d == Decimal.MinValue);
825
826                         d = new Decimal (parts6);
827                         int [] erg = Decimal.GetBits (d);
828                         for (int i = 0; i < 4; i++) {
829                                 Assert.IsTrue (erg [i] == parts6 [i]);
830                         }
831                 }
832
833                 [Test]
834                 public void TestFloorTruncate ()
835                 {
836                         decimal [,] dtab = {
837                                 {0m, 0m, 0m}, {1m, 1m, 1m}, {-1m, -1m, -1m}, {1.1m, 1m, 1m}, 
838                                 {-1.000000000001m, -2m, -1m}, {12345.67890m,12345m,12345m},
839                                 {-123456789012345.67890m, -123456789012346m, -123456789012345m},
840                                 {Decimal.MaxValue, Decimal.MaxValue, Decimal.MaxValue},
841                                 {Decimal.MinValue, Decimal.MinValue, Decimal.MinValue},
842                                 {6.999999999m, 6m, 6m}, {-6.999999999m, -7m, -6m}, 
843                                 {0.00001m, 0m, 0m}, {-0.00001m, -1m, 0m}
844                         };
845
846                         decimal d;
847
848                         for (int i = 0; i < dtab.GetLength (0); i++) {
849                                 d = Decimal.Floor (dtab [i, 0]);
850                                 if (d != dtab [i, 1]) {
851                                         Assert.Fail ("Floor: Floor(" + dtab [i, 0] + ") != " + d);
852                                 }
853                                 d = Decimal.Truncate (dtab [i, 0]);
854                                 if (d != dtab [i, 2]) {
855                                         Assert.Fail ("Truncate: Truncate(" + dtab [i, 0] + ") != " + d);
856                                 }
857                         }
858                 }
859
860                 [Test]
861                 public void Truncate ()
862                 {
863                         decimal dd = 249.9m;
864                         decimal dt = Decimal.Truncate (dd);
865                         Assert.AreEqual (249.9m, dd, "Original");
866                         Assert.AreEqual (249m, dt, "Truncate");
867                         Assert.AreEqual (249, (byte) dd, "Cast-Byte");
868                         Assert.AreEqual (249, (char) dd, "Cast-Char");
869                         Assert.AreEqual (249, (short) dd, "Cast-Int16");
870                         Assert.AreEqual (249, (ushort) dd, "Cast-UInt16");
871                         Assert.AreEqual (249, (int) dd, "Cast-Int32");
872                         Assert.AreEqual (249, (uint) dd, "Cast-UInt32");
873                         Assert.AreEqual (249, (long) dd, "Cast-Int64");
874                         Assert.AreEqual (249, (ulong) dd, "Cast-UInt64");
875                 }
876
877                 [Test]
878                 public void TestRound ()
879                 {
880                         decimal [,] dtab = { 
881                                 {1m, 0, 1m}, {1.234567890m, 1, 1.2m}, 
882                                 {1.234567890m, 2, 1.23m}, {1.23450000001m, 3, 1.235m}, 
883                                 {1.2355m, 3, 1.236m}, 
884                                 {1.234567890m, 4, 1.2346m}, {1.23567890m, 2, 1.24m}, 
885                                 {47893764694.4578563236436621m, 7, 47893764694.4578563m},
886                                 {-47893764694.4578563236436621m, 9, -47893764694.457856324m},
887                                 {-47893764694.4578m, 5, -47893764694.4578m}
888                         };
889
890                         decimal d;
891
892                         for (int i = 0; i < dtab.GetLength (0); i++) {
893                                 d = Decimal.Round (dtab [i, 0], (int) dtab [i, 1]);
894                                 if (d != dtab [i, 2]) {
895                                         Assert.Fail ("Round: Round(" + dtab [i, 0] + "," + (int) dtab [i, 1] + ") != " + d);
896                                 }
897                         }
898                 }
899
900                 [Test]
901                 public void TestRoundFailures ()
902                 {
903                         decimal [,] dtab = {
904                                 {1.2345m, 3, 1.234m} 
905                         };
906
907                         decimal d;
908
909                         for (int i = 0; i < dtab.GetLength (0); i++) {
910                                 d = Decimal.Round (dtab [i, 0], (int) dtab [i, 1]);
911                                 if (d != dtab [i, 2]) {
912                                         Assert.Fail ("FailRound: Round(" + dtab [i, 0] + "," + (int) dtab [i, 1] + ") != " + d);
913                                 }
914                         }
915                 }
916
917                 [Test]
918                 public void ParseInt64 ()
919                 {
920                         long max = Int64.MaxValue;
921                         Decimal dmax = Decimal.Parse (max.ToString ());
922                         Assert.AreEqual (Int64.MaxValue, Decimal.ToInt64 (dmax), "Int64.MaxValue");
923
924                         long min = Int64.MinValue;
925                         Decimal dmin = Decimal.Parse (min.ToString ());
926                         Assert.AreEqual (Int64.MinValue, Decimal.ToInt64 (dmin), "Int64.MinValue");
927
928                         dmax += 1.1m;
929                         dmax = Decimal.Parse (dmax.ToString ());
930                         Assert.AreEqual (Int64.MaxValue, Decimal.ToInt64 (dmax - 1.1m), "Int64.MaxValue+1.1");
931
932                         dmin -= 1.1m;
933                         dmin = Decimal.Parse (dmin.ToString ());
934                         Assert.AreEqual (Int64.MinValue, Decimal.ToInt64 (dmin + 1.1m), "Int64.MinValue-1.1");
935                 }
936
937                 [Test]
938                 public void ToByte ()
939                 {
940                         Decimal d = 254.9m;
941                         Assert.AreEqual (254, Decimal.ToByte (d), "Decimal.ToByte");
942                         Assert.AreEqual (255, Convert.ToByte (d), "Convert.ToByte");
943                         Assert.AreEqual (255, (d as IConvertible).ToByte (null), "IConvertible.ToByte");
944                 }
945
946                 [Test]
947                 public void ToSByte ()
948                 {
949                         Decimal d = 126.9m;
950                         Assert.AreEqual (126, Decimal.ToSByte (d), "Decimal.ToSByte");
951                         Assert.AreEqual (127, Convert.ToSByte (d), "Convert.ToSByte");
952                         Assert.AreEqual (127, (d as IConvertible).ToSByte (null), "IConvertible.ToSByte");
953                         d = -d;
954                         Assert.AreEqual (-126, Decimal.ToSByte (d), "-Decimal.ToSByte");
955                         Assert.AreEqual (-127, Convert.ToSByte (d), "-Convert.ToSByte");
956                         Assert.AreEqual (-127, (d as IConvertible).ToSByte (null), "-IConvertible.ToSByte");
957                 }
958
959                 [Test]
960                 public void ToInt16 ()
961                 {
962                         Decimal d = 254.9m;
963                         Assert.AreEqual (254, Decimal.ToInt16 (d), "Decimal.ToInt16");
964                         Assert.AreEqual (255, Convert.ToInt16 (d), "Convert.ToInt16");
965                         Assert.AreEqual (255, (d as IConvertible).ToInt16 (null), "IConvertible.ToInt16");
966                         d = -d;
967                         Assert.AreEqual (-254, Decimal.ToInt16 (d), "-Decimal.ToInt16");
968                         Assert.AreEqual (-255, Convert.ToInt16 (d), "-Convert.ToInt16");
969                         Assert.AreEqual (-255, (d as IConvertible).ToInt16 (null), "-IConvertible.ToInt16");
970                 }
971
972                 [Test]
973                 public void ToUInt16 ()
974                 {
975                         Decimal d = 254.9m;
976                         Assert.AreEqual (254, Decimal.ToUInt16 (d), "Decimal.ToUInt16");
977                         Assert.AreEqual (255, Convert.ToUInt16 (d), "Convert.ToUInt16");
978                         Assert.AreEqual (255, (d as IConvertible).ToUInt16 (null), "IConvertible.ToUInt16");
979                 }
980
981                 [Test]
982                 public void ToInt32 ()
983                 {
984                         Decimal d = 254.9m;
985                         Assert.AreEqual (254, Decimal.ToInt32 (d), "Decimal.ToInt32");
986                         Assert.AreEqual (255, Convert.ToInt32 (d), "Convert.ToInt32");
987                         Assert.AreEqual (255, (d as IConvertible).ToInt32 (null), "IConvertible.ToInt32");
988                         d = -d;
989                         Assert.AreEqual (-254, Decimal.ToInt32 (d), "-Decimal.ToInt32");
990                         Assert.AreEqual (-255, Convert.ToInt32 (d), "-Convert.ToInt32");
991                         Assert.AreEqual (-255, (d as IConvertible).ToInt32 (null), "-IConvertible.ToInt32");
992                 }
993
994                 [Test]
995                 public void ToUInt32 ()
996                 {
997                         Decimal d = 254.9m;
998                         Assert.AreEqual (254, Decimal.ToUInt32 (d), "Decimal.ToUInt32");
999                         Assert.AreEqual (255, Convert.ToUInt32 (d), "Convert.ToUInt32");
1000                         Assert.AreEqual (255, (d as IConvertible).ToUInt32 (null), "IConvertible.ToUInt32");
1001                 }
1002
1003                 [Test]
1004                 public void ToInt64 ()
1005                 {
1006                         Decimal d = 254.9m;
1007                         Assert.AreEqual (254, Decimal.ToInt64 (d), "Decimal.ToInt64");
1008                         Assert.AreEqual (255, Convert.ToInt64 (d), "Convert.ToInt64");
1009                         Assert.AreEqual (255, (d as IConvertible).ToInt64 (null), "IConvertible.ToInt64");
1010                         d = -d;
1011                         Assert.AreEqual (-254, Decimal.ToInt64 (d), "-Decimal.ToInt64");
1012                         Assert.AreEqual (-255, Convert.ToInt64 (d), "-Convert.ToInt64");
1013                         Assert.AreEqual (-255, (d as IConvertible).ToInt64 (null), "-IConvertible.ToInt64");
1014                 }
1015
1016                 [Test]
1017                 [ExpectedException (typeof (OverflowException))]
1018                 public void ToInt64_TooBig ()
1019                 {
1020                         Decimal d = (Decimal) Int64.MaxValue;
1021                         d += 1.1m;
1022                         long value = Decimal.ToInt64 (d);
1023                 }
1024
1025                 [Test]
1026                 [ExpectedException (typeof (OverflowException))]
1027                 public void ToInt64_TooSmall ()
1028                 {
1029                         Decimal d = (Decimal) Int64.MinValue;
1030                         d -= 1.1m;
1031                         long value = Decimal.ToInt64 (d);
1032                 }
1033
1034                 [Test]
1035                 public void ToUInt64 ()
1036                 {
1037                         Decimal d = 254.9m;
1038                         Assert.AreEqual (254, Decimal.ToUInt64 (d), "Decimal.ToUInt64");
1039                         Assert.AreEqual (255, Convert.ToUInt64 (d), "Convert.ToUInt64");
1040                         Assert.AreEqual (255, (d as IConvertible).ToUInt64 (null), "IConvertible.ToUInt64");
1041                 }
1042
1043                 [Test]
1044                 public void ToSingle ()
1045                 {
1046                         Decimal d = 254.9m;
1047                         Assert.AreEqual (254.9f, Decimal.ToSingle (d), "Decimal.ToSingle");
1048                         Assert.AreEqual (254.9f, Convert.ToSingle (d), "Convert.ToSingle");
1049                         Assert.AreEqual (254.9f, (d as IConvertible).ToSingle (null), "IConvertible.ToSingle");
1050                         d = -d;
1051                         Assert.AreEqual (-254.9f, Decimal.ToSingle (d), "-Decimal.ToSingle");
1052                         Assert.AreEqual (-254.9f, Convert.ToSingle (d), "-Convert.ToSingle");
1053                         Assert.AreEqual (-254.9f, (d as IConvertible).ToSingle (null), "-IConvertible.ToSingle");
1054                 }
1055
1056                 [Test]
1057                 public void ToDouble ()
1058                 {
1059                         Decimal d = 254.9m;
1060                         Assert.AreEqual (254.9d, Decimal.ToDouble (d), "Decimal.ToDouble");
1061                         Assert.AreEqual (254.9d, Convert.ToDouble (d), "Convert.ToDouble");
1062                         Assert.AreEqual (254.9d, (d as IConvertible).ToDouble (null), "IConvertible.ToDouble");
1063                         d = -d;
1064                         Assert.AreEqual (-254.9d, Decimal.ToDouble (d), "-Decimal.ToDouble");
1065                         Assert.AreEqual (-254.9d, Convert.ToDouble (d), "-Convert.ToDouble");
1066                         Assert.AreEqual (-254.9d, (d as IConvertible).ToDouble (null), "-IConvertible.ToDouble");
1067                 }
1068
1069                 [Test]
1070                 [SetCulture("en-US")]
1071                 public void ToString_Defaults ()
1072                 {
1073                         Decimal d = 254.9m;
1074                         // everything defaults to "G"
1075                         string def = d.ToString ("G");
1076                         Assert.AreEqual (def, d.ToString (), "ToString()");
1077                         Assert.AreEqual (def, d.ToString ((IFormatProvider) null), "ToString((IFormatProvider)null)");
1078                         Assert.AreEqual (def, d.ToString ((string) null), "ToString((string)null)");
1079                         Assert.AreEqual (def, d.ToString (String.Empty), "ToString(empty)");
1080                         Assert.AreEqual (def, d.ToString (null, null), "ToString(null,null)");
1081                         Assert.AreEqual (def, d.ToString (String.Empty, null), "ToString(empty,null)");
1082
1083                         Assert.AreEqual ("254.9", def, "ToString()");
1084                 }
1085
1086                 [Test]
1087                 public void CastTruncRounding ()
1088                 {
1089                         // casting truncs decimal value (not normal nor banker's rounding)
1090                         Assert.AreEqual (254, (long) (254.9m), "254.9==254");
1091                         Assert.AreEqual (-254, (long) (-254.9m), "-254.9=-254");
1092                         Assert.AreEqual (255, (long) (255.9m), "255.9==256");
1093                         Assert.AreEqual (-255, (long) (-255.9m), "-255.9=-256");
1094                 }
1095
1096                 [Test]
1097                 public void ParseFractions ()
1098                 {
1099                         decimal d1 = Decimal.Parse ("0.523456789012345467890123456789", CultureInfo.InvariantCulture);
1100                         Assert.AreEqual (0.5234567890123454678901234568m, d1, "f1");
1101                         decimal d2 = Decimal.Parse ("0.49214206543486529434634231456", CultureInfo.InvariantCulture);
1102                         Assert.AreEqual (0.4921420654348652943463423146m, d2, "f2");
1103                 }
1104
1105                 [Test]
1106                 [ExpectedException (typeof (OverflowException))]
1107                 public void Parse_Int64_Overflow ()
1108                 {
1109                         // Int64.MaxValue + 1 + small fraction to allow 30 digits
1110                         // 123456789012345678901234567890
1111                         decimal d = Decimal.Parse ("9223372036854775808.0000000009", CultureInfo.InvariantCulture);
1112                         long l = (long) d;
1113                 }
1114 /* Not yet fixed
1115                 [Test]
1116                 public void ParseEmptyNumberGroupSeparator ()
1117                 {
1118                         CultureInfo originalCulture = CultureInfo.CurrentCulture;
1119                         Thread.CurrentThread.CurrentCulture = new CultureInfo ("en-US");
1120                         try {
1121                                 var nf = new NumberFormatInfo ();
1122                                 nf.NumberDecimalSeparator = ".";
1123                                 nf.NumberGroupSeparator = "";
1124                                 decimal d = decimal.Parse ("4.5", nf);
1125                                 Assert.AreEqual (4.5, d);
1126                         } finally {
1127                                 Thread.CurrentThread.CurrentCulture = originalCulture;
1128                         }
1129                 }
1130 */
1131
1132                 [Test]
1133                 public void ParseCultureSeparator ()
1134                 {
1135                         Assert.AreEqual (2.2m, decimal.Parse ("2.2", new CultureInfo("es-MX")));
1136                 }
1137
1138                 [Test]
1139                 public void TryParse ()
1140                 {
1141                         Decimal r;
1142                 
1143                         // These should return false
1144                         Assert.AreEqual (false, Decimal.TryParse ("79228162514264337593543950336", out r));
1145                         Assert.AreEqual (false, Decimal.TryParse ("123nx", NumberStyles.Number, CultureInfo.InvariantCulture, out r));
1146                         Assert.AreEqual (false, Decimal.TryParse (null, NumberStyles.Number, CultureInfo.InvariantCulture, out r));
1147
1148                         // These should pass
1149                         for (int i = 0; i < tab.Length; i++) {
1150                                 Assert.AreEqual (!tab [i].exceptionFlag,
1151                                         Decimal.TryParse (tab [i].str, tab [i].style,
1152                                         NumberFormatInfo.InvariantInfo, out r));
1153                         }
1154                 }
1155
1156                 [Test]
1157                 [ExpectedException (typeof (DivideByZeroException))]
1158                 public void Remainder_ByZero ()
1159                 {
1160                         Decimal.Remainder (254.9m, 0m);
1161                 }
1162
1163                 [Test]
1164                 public void Remainder ()
1165                 {
1166                         decimal p1 = 254.9m;
1167                         decimal p2 = 12.1m;
1168                         decimal n1 = -254.9m;
1169                         decimal n2 = -12.1m;
1170
1171                         Assert.AreEqual (0.8m, Decimal.Remainder (p1, p2), "254.9 % 12.1");
1172                         Assert.AreEqual (-0.8m, Decimal.Remainder (n1, p2), "-254.9 % 12.1");
1173                         Assert.AreEqual (0.8m, Decimal.Remainder (p1, n2), "254.9 % -12.1");
1174                         Assert.AreEqual (-0.8m, Decimal.Remainder (n1, n2), "-254.9 % -12.1");
1175
1176                         Assert.AreEqual (12.1m, Decimal.Remainder (p2, p1), "12.1 % 254.9");
1177                         Assert.AreEqual (-12.1m, Decimal.Remainder (n2, p1), "-12.1 % 254.9");
1178                         Assert.AreEqual (12.1m, Decimal.Remainder (p2, n1), "12.1 % -254.9");
1179                         Assert.AreEqual (-12.1m, Decimal.Remainder (n2, n1), "-12.1 % -254.9");
1180
1181                         Assert.AreEqual (0.0m, Decimal.Remainder (p1, p1), "12.1 % 12.1");
1182                         Assert.AreEqual (0.0m, Decimal.Remainder (n1, p1), "-12.1 % 12.1");
1183                         Assert.AreEqual (0.0m, Decimal.Remainder (p1, n1), "12.1 % -12.1");
1184                         Assert.AreEqual (0.0m, Decimal.Remainder (n1, n1), "-12.1 % -12.1");
1185                 }
1186
1187                 [Test]
1188                 public void Remainder2 ()
1189                 {
1190                         decimal a = 20.0M;
1191                         decimal b = 10.0M;
1192                         decimal c = 10.00M;
1193
1194                         Assert.AreEqual (0.00m, a % c, "20.0M % 10.00M");
1195                 
1196                 }
1197
1198                 [Test]
1199                 [ExpectedException (typeof (DivideByZeroException))]
1200                 public void Divide_ByZero ()
1201                 {
1202                         Decimal.Divide (254.9m, 0m);
1203                 }
1204
1205                 [Test]
1206                 public void Divide ()
1207                 {
1208                         decimal p1 = 254.9m;
1209                         decimal p2 = 12.1m;
1210                         decimal n1 = -254.9m;
1211                         decimal n2 = -12.1m;
1212
1213                         decimal c1 = 21.066115702479338842975206612m;
1214                         decimal c2 = 0.0474695959199686151431934092m;
1215
1216                         Assert.AreEqual (c1, Decimal.Divide (p1, p2), "254.9 / 12.1");
1217                         Assert.AreEqual (-c1, Decimal.Divide (n1, p2), "-254.9 / 12.1");
1218                         Assert.AreEqual (-c1, Decimal.Divide (p1, n2), "254.9 / -12.1");
1219                         Assert.AreEqual (c1, Decimal.Divide (n1, n2), "-254.9 / -12.1");
1220
1221                         Assert.AreEqual (c2, Decimal.Divide (p2, p1), "12.1 / 254.9");
1222                         Assert.AreEqual (-c2, Decimal.Divide (n2, p1), "-12.1 / 254.9");
1223                         Assert.AreEqual (-c2, Decimal.Divide (p2, n1), "12.1 / -254.9");
1224                         Assert.AreEqual (c2, Decimal.Divide (n2, n1), "-12.1 / -254.9");
1225
1226                         Assert.AreEqual (1, Decimal.Divide (p1, p1), "12.1 / 12.1");
1227                         Assert.AreEqual (-1, Decimal.Divide (n1, p1), "-12.1 / 12.1");
1228                         Assert.AreEqual (-1, Decimal.Divide (p1, n1), "12.1 / -12.1");
1229                         Assert.AreEqual (1, Decimal.Divide (n1, n1), "-12.1 / -12.1");
1230                 }
1231
1232                 [Test]
1233                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1234                 public void Round_InvalidDecimals_Negative ()
1235                 {
1236                         Decimal.Round (254.9m, -1);
1237                 }
1238
1239                 [Test]
1240                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1241                 public void Round_InvalidDecimals_TooHigh ()
1242                 {
1243                         Decimal.Round (254.9m, 29);
1244                 }
1245
1246                 [Test]
1247                 public void Round_OddValue ()
1248                 {
1249                         decimal five = 5.5555555555555555555555555555m;
1250                         Assert.AreEqual (6, Decimal.Round (five, 0), "5,5_,00");
1251                         Assert.AreEqual (5.6m, Decimal.Round (five, 1), "5,5_,01");
1252                         Assert.AreEqual (5.56m, Decimal.Round (five, 2), "5,5_,02");
1253                         Assert.AreEqual (5.556m, Decimal.Round (five, 3), "5,5_,03");
1254                         Assert.AreEqual (5.5556m, Decimal.Round (five, 4), "5,5_,04");
1255                         Assert.AreEqual (5.55556m, Decimal.Round (five, 5), "5,5_,05");
1256                         Assert.AreEqual (5.555556m, Decimal.Round (five, 6), "5,5_,06");
1257                         Assert.AreEqual (5.5555556m, Decimal.Round (five, 7), "5,5_,07");
1258                         Assert.AreEqual (5.55555556m, Decimal.Round (five, 8), "5,5_,08");
1259                         Assert.AreEqual (5.555555556m, Decimal.Round (five, 9), "5,5_,09");
1260                         Assert.AreEqual (5.5555555556m, Decimal.Round (five, 10), "5,5_,10");
1261                         Assert.AreEqual (5.55555555556m, Decimal.Round (five, 11), "5,5_,11");
1262                         Assert.AreEqual (5.555555555556m, Decimal.Round (five, 12), "5,5_,12");
1263                         Assert.AreEqual (5.5555555555556m, Decimal.Round (five, 13), "5,5_,13");
1264                         Assert.AreEqual (5.55555555555556m, Decimal.Round (five, 14), "5,5_,14");
1265                         Assert.AreEqual (5.555555555555556m, Decimal.Round (five, 15), "5,5_,15");
1266                         Assert.AreEqual (5.5555555555555556m, Decimal.Round (five, 16), "5,5_,16");
1267                         Assert.AreEqual (5.55555555555555556m, Decimal.Round (five, 17), "5,5_,17");
1268                         Assert.AreEqual (5.555555555555555556m, Decimal.Round (five, 18), "5,5_,18");
1269                         Assert.AreEqual (5.5555555555555555556m, Decimal.Round (five, 19), "5,5_,19");
1270                         Assert.AreEqual (5.55555555555555555556m, Decimal.Round (five, 20), "5,5_,20");
1271                         Assert.AreEqual (5.555555555555555555556m, Decimal.Round (five, 21), "5,5_,21");
1272                         Assert.AreEqual (5.5555555555555555555556m, Decimal.Round (five, 22), "5,5_,22");
1273                         Assert.AreEqual (5.55555555555555555555556m, Decimal.Round (five, 23), "5,5_,23");
1274                         Assert.AreEqual (5.555555555555555555555556m, Decimal.Round (five, 24), "5,5_,24");
1275                         Assert.AreEqual (5.5555555555555555555555556m, Decimal.Round (five, 25), "5,5_,25");
1276                         Assert.AreEqual (5.55555555555555555555555556m, Decimal.Round (five, 26), "5,5_,26");
1277                         Assert.AreEqual (5.555555555555555555555555556m, Decimal.Round (five, 27), "5,5_,27");
1278                         Assert.AreEqual (5.5555555555555555555555555555m, Decimal.Round (five, 28), "5.5_,28");
1279                 }
1280
1281                 [Test]
1282                 public void Round_EvenValue ()
1283                 {
1284                         Assert.AreEqual (2, Decimal.Round (2.5m, 0), "2,2_5,00");
1285                         Assert.AreEqual (2.2m, Decimal.Round (2.25m, 1), "2,2_5,01");
1286                         Assert.AreEqual (2.22m, Decimal.Round (2.225m, 2), "2,2_5,02");
1287                         Assert.AreEqual (2.222m, Decimal.Round (2.2225m, 3), "2,2_5,03");
1288                         Assert.AreEqual (2.2222m, Decimal.Round (2.22225m, 4), "2,2_5,04");
1289                         Assert.AreEqual (2.22222m, Decimal.Round (2.222225m, 5), "2,2_5,05");
1290                         Assert.AreEqual (2.222222m, Decimal.Round (2.2222225m, 6), "2,2_5,06");
1291                         Assert.AreEqual (2.2222222m, Decimal.Round (2.22222225m, 7), "2,2_5,07");
1292                         Assert.AreEqual (2.22222222m, Decimal.Round (2.222222225m, 8), "2,2_5,08");
1293                         Assert.AreEqual (2.222222222m, Decimal.Round (2.2222222225m, 9), "2,2_5,09");
1294                         Assert.AreEqual (2.2222222222m, Decimal.Round (2.22222222225m, 10), "2,2_5,10");
1295                         Assert.AreEqual (2.22222222222m, Decimal.Round (2.222222222225m, 11), "2,2_5,11");
1296                         Assert.AreEqual (2.222222222222m, Decimal.Round (2.2222222222225m, 12), "2,2_5,12");
1297                         Assert.AreEqual (2.2222222222222m, Decimal.Round (2.22222222222225m, 13), "2,2_5,13");
1298                         Assert.AreEqual (2.22222222222222m, Decimal.Round (2.222222222222225m, 14), "2,2_5,14");
1299                         Assert.AreEqual (2.222222222222222m, Decimal.Round (2.2222222222222225m, 15), "2,2_5,15");
1300                         Assert.AreEqual (2.2222222222222222m, Decimal.Round (2.22222222222222225m, 16), "2,2_5,16");
1301                         Assert.AreEqual (2.22222222222222222m, Decimal.Round (2.222222222222222225m, 17), "2,2_5,17");
1302                         Assert.AreEqual (2.222222222222222222m, Decimal.Round (2.2222222222222222225m, 18), "2,2_5,18");
1303                         Assert.AreEqual (2.2222222222222222222m, Decimal.Round (2.22222222222222222225m, 19), "2,2_5,19");
1304                         Assert.AreEqual (2.22222222222222222222m, Decimal.Round (2.222222222222222222225m, 20), "2,2_5,20");
1305                         Assert.AreEqual (2.222222222222222222222m, Decimal.Round (2.2222222222222222222225m, 21), "2,2_5,21");
1306                         Assert.AreEqual (2.2222222222222222222222m, Decimal.Round (2.22222222222222222222225m, 22), "2,2_5,22");
1307                         Assert.AreEqual (2.22222222222222222222222m, Decimal.Round (2.222222222222222222222225m, 23), "2,2_5,23");
1308                         Assert.AreEqual (2.222222222222222222222222m, Decimal.Round (2.2222222222222222222222225m, 24), "2,2_5,24");
1309                         Assert.AreEqual (2.2222222222222222222222222m, Decimal.Round (2.22222222222222222222222225m, 25), "2,2_5,25");
1310                         Assert.AreEqual (2.22222222222222222222222222m, Decimal.Round (2.222222222222222222222222225m, 26), "2,2_5,26");
1311                         Assert.AreEqual (2.222222222222222222222222222m, Decimal.Round (2.2222222222222222222222222225m, 27), "2,2_5,27");
1312                         Assert.AreEqual (2.2222222222222222222222222222m, Decimal.Round (2.22222222222222222222222222225m, 28), "2,2_5,28");
1313                 }
1314
1315                 [Test]
1316                 public void Round_OddValue_Negative ()
1317                 {
1318                         decimal five = -5.5555555555555555555555555555m;
1319                         Assert.AreEqual (-6, Decimal.Round (five, 0), "-5,5_,00");
1320                         Assert.AreEqual (-5.6m, Decimal.Round (five, 1), "-5,5_,01");
1321                         Assert.AreEqual (-5.56m, Decimal.Round (five, 2), "-5,5_,02");
1322                         Assert.AreEqual (-5.556m, Decimal.Round (five, 3), "-5,5_,03");
1323                         Assert.AreEqual (-5.5556m, Decimal.Round (five, 4), "-5,5_,04");
1324                         Assert.AreEqual (-5.55556m, Decimal.Round (five, 5), "-5,5_,05");
1325                         Assert.AreEqual (-5.555556m, Decimal.Round (five, 6), "-5,5_,06");
1326                         Assert.AreEqual (-5.5555556m, Decimal.Round (five, 7), "-5,5_,07");
1327                         Assert.AreEqual (-5.55555556m, Decimal.Round (five, 8), "-5,5_,08");
1328                         Assert.AreEqual (-5.555555556m, Decimal.Round (five, 9), "-5,5_,09");
1329                         Assert.AreEqual (-5.5555555556m, Decimal.Round (five, 10), "-5,5_,10");
1330                         Assert.AreEqual (-5.55555555556m, Decimal.Round (five, 11), "-5,5_,11");
1331                         Assert.AreEqual (-5.555555555556m, Decimal.Round (five, 12), "-5,5_,12");
1332                         Assert.AreEqual (-5.5555555555556m, Decimal.Round (five, 13), "-5,5_,13");
1333                         Assert.AreEqual (-5.55555555555556m, Decimal.Round (five, 14), "-5,5_,14");
1334                         Assert.AreEqual (-5.555555555555556m, Decimal.Round (five, 15), "-5,5_,15");
1335                         Assert.AreEqual (-5.5555555555555556m, Decimal.Round (five, 16), "-5,5_,16");
1336                         Assert.AreEqual (-5.55555555555555556m, Decimal.Round (five, 17), "-5,5_,17");
1337                         Assert.AreEqual (-5.555555555555555556m, Decimal.Round (five, 18), "-5,5_,18");
1338                         Assert.AreEqual (-5.5555555555555555556m, Decimal.Round (five, 19), "-5,5_,19");
1339                         Assert.AreEqual (-5.55555555555555555556m, Decimal.Round (five, 20), "-5,5_,20");
1340                         Assert.AreEqual (-5.555555555555555555556m, Decimal.Round (five, 21), "-5,5_,21");
1341                         Assert.AreEqual (-5.5555555555555555555556m, Decimal.Round (five, 22), "-5,5_,22");
1342                         Assert.AreEqual (-5.55555555555555555555556m, Decimal.Round (five, 23), "-5,5_,23");
1343                         Assert.AreEqual (-5.555555555555555555555556m, Decimal.Round (five, 24), "-5,5_,24");
1344                         Assert.AreEqual (-5.5555555555555555555555556m, Decimal.Round (five, 25), "-5,5_,25");
1345                         Assert.AreEqual (-5.55555555555555555555555556m, Decimal.Round (five, 26), "-5,5_,26");
1346                         Assert.AreEqual (-5.555555555555555555555555556m, Decimal.Round (five, 27), "-5,5_,27");
1347                         Assert.AreEqual (-5.5555555555555555555555555555m, Decimal.Round (five, 28), "-5.5_,28");
1348                 }
1349
1350                 [Test]
1351                 public void Round_EvenValue_Negative ()
1352                 {
1353                         Assert.AreEqual (-2, Decimal.Round (-2.5m, 0), "-2,2_5,00");
1354                         Assert.AreEqual (-2.2m, Decimal.Round (-2.25m, 1), "-2,2_5,01");
1355                         Assert.AreEqual (-2.22m, Decimal.Round (-2.225m, 2), "-2,2_5,02");
1356                         Assert.AreEqual (-2.222m, Decimal.Round (-2.2225m, 3), "-2,2_5,03");
1357                         Assert.AreEqual (-2.2222m, Decimal.Round (-2.22225m, 4), "-2,2_5,04");
1358                         Assert.AreEqual (-2.22222m, Decimal.Round (-2.222225m, 5), "-2,2_5,05");
1359                         Assert.AreEqual (-2.222222m, Decimal.Round (-2.2222225m, 6), "-2,2_5,06");
1360                         Assert.AreEqual (-2.2222222m, Decimal.Round (-2.22222225m, 7), "-2,2_5,07");
1361                         Assert.AreEqual (-2.22222222m, Decimal.Round (-2.222222225m, 8), "-2,2_5,08");
1362                         Assert.AreEqual (-2.222222222m, Decimal.Round (-2.2222222225m, 9), "-2,2_5,09");
1363                         Assert.AreEqual (-2.2222222222m, Decimal.Round (-2.22222222225m, 10), "-2,2_5,10");
1364                         Assert.AreEqual (-2.22222222222m, Decimal.Round (-2.222222222225m, 11), "-2,2_5,11");
1365                         Assert.AreEqual (-2.222222222222m, Decimal.Round (-2.2222222222225m, 12), "-2,2_5,12");
1366                         Assert.AreEqual (-2.2222222222222m, Decimal.Round (-2.22222222222225m, 13), "-2,2_5,13");
1367                         Assert.AreEqual (-2.22222222222222m, Decimal.Round (-2.222222222222225m, 14), "-2,2_5,14");
1368                         Assert.AreEqual (-2.222222222222222m, Decimal.Round (-2.2222222222222225m, 15), "-2,2_5,15");
1369                         Assert.AreEqual (-2.2222222222222222m, Decimal.Round (-2.22222222222222225m, 16), "-2,2_5,16");
1370                         Assert.AreEqual (-2.22222222222222222m, Decimal.Round (-2.222222222222222225m, 17), "-2,2_5,17");
1371                         Assert.AreEqual (-2.222222222222222222m, Decimal.Round (-2.2222222222222222225m, 18), "-2,2_5,18");
1372                         Assert.AreEqual (-2.2222222222222222222m, Decimal.Round (-2.22222222222222222225m, 19), "-2,2_5,19");
1373                         Assert.AreEqual (-2.22222222222222222222m, Decimal.Round (-2.222222222222222222225m, 20), "-2,2_5,20");
1374                         Assert.AreEqual (-2.222222222222222222222m, Decimal.Round (-2.2222222222222222222225m, 21), "-2,2_5,21");
1375                         Assert.AreEqual (-2.2222222222222222222222m, Decimal.Round (-2.22222222222222222222225m, 22), "-2,2_5,22");
1376                         Assert.AreEqual (-2.22222222222222222222222m, Decimal.Round (-2.222222222222222222222225m, 23), "-2,2_5,23");
1377                         Assert.AreEqual (-2.222222222222222222222222m, Decimal.Round (-2.2222222222222222222222225m, 24), "-2,2_5,24");
1378                         Assert.AreEqual (-2.2222222222222222222222222m, Decimal.Round (-2.22222222222222222222222225m, 25), "-2,2_5,25");
1379                         Assert.AreEqual (-2.22222222222222222222222222m, Decimal.Round (-2.222222222222222222222222225m, 26), "-2,2_5,26");
1380                         Assert.AreEqual (-2.222222222222222222222222222m, Decimal.Round (-2.2222222222222222222222222225m, 27), "-2,2_5,27");
1381                         Assert.AreEqual (-2.2222222222222222222222222222m, Decimal.Round (-2.22222222222222222222222222225m, 28), "-2,2_5,28");
1382                 }
1383
1384                 [Test] // bug #59425
1385                 [SetCulture("en-US")]
1386                 public void ParseAndKeepPrecision ()
1387                 {
1388                         string value = "5";
1389                         Assert.AreEqual (value, value, Decimal.Parse (value).ToString ());
1390                         value += '.';
1391                         for (int i = 0; i < 28; i++) {
1392                                 value += "0";
1393                                 Assert.AreEqual (value, Decimal.Parse (value).ToString (), i.ToString ());
1394                         }
1395
1396                         value = "-5";
1397                         Assert.AreEqual (value, value, Decimal.Parse (value).ToString ());
1398                         value += '.';
1399                         for (int i = 0; i < 28; i++) {
1400                                 value += "0";
1401                                 Assert.AreEqual (value, Decimal.Parse (value).ToString (), "-" + i.ToString ());
1402                         }
1403                 }
1404
1405                 [Test]
1406                 [SetCulture("en-US")]
1407                 public void ToString_G ()
1408                 {
1409                         Assert.AreEqual ("1.0", (1.0m).ToString (), "00");
1410                         Assert.AreEqual ("0.1", (0.1m).ToString (), "01");
1411                         Assert.AreEqual ("0.01", (0.01m).ToString (), "02");
1412                         Assert.AreEqual ("0.001", (0.001m).ToString (), "03");
1413                         Assert.AreEqual ("0.0001", (0.0001m).ToString (), "04");
1414                         Assert.AreEqual ("0.00001", (0.00001m).ToString (), "05");
1415                         Assert.AreEqual ("0.000001", (0.000001m).ToString (), "06");
1416                         Assert.AreEqual ("0.0000001", (0.0000001m).ToString (), "07");
1417                         Assert.AreEqual ("0.00000001", (0.00000001m).ToString (), "08");
1418                         Assert.AreEqual ("0.000000001", (0.000000001m).ToString (), "09");
1419                         Assert.AreEqual ("0.0000000001", (0.0000000001m).ToString (), "10");
1420                         Assert.AreEqual ("0.00000000001", (0.00000000001m).ToString (), "11");
1421                         Assert.AreEqual ("0.000000000001", (0.000000000001m).ToString (), "12");
1422                         Assert.AreEqual ("0.0000000000001", (0.0000000000001m).ToString (), "13");
1423                         Assert.AreEqual ("0.00000000000001", (0.00000000000001m).ToString (), "14");
1424                         Assert.AreEqual ("0.000000000000001", (0.000000000000001m).ToString (), "15");
1425                         Assert.AreEqual ("0.0000000000000001", (0.0000000000000001m).ToString (), "16");
1426                         Assert.AreEqual ("0.00000000000000001", (0.00000000000000001m).ToString (), "17");
1427                         Assert.AreEqual ("0.000000000000000001", (0.000000000000000001m).ToString (), "18");
1428                         Assert.AreEqual ("0.0000000000000000001", (0.0000000000000000001m).ToString (), "19");
1429                         Assert.AreEqual ("0.00000000000000000001", (0.00000000000000000001m).ToString (), "20");
1430                         Assert.AreEqual ("0.000000000000000000001", (0.000000000000000000001m).ToString (), "21");
1431                         Assert.AreEqual ("0.0000000000000000000001", (0.0000000000000000000001m).ToString (), "22");
1432                         Assert.AreEqual ("0.00000000000000000000001", (0.00000000000000000000001m).ToString (), "23");
1433                         Assert.AreEqual ("0.000000000000000000000001", (0.000000000000000000000001m).ToString (), "24");
1434                         Assert.AreEqual ("0.0000000000000000000000001", (0.0000000000000000000000001m).ToString (), "25");
1435                         Assert.AreEqual ("0.00000000000000000000000001", (0.00000000000000000000000001m).ToString (), "26");
1436                         Assert.AreEqual ("0.000000000000000000000000001", (0.000000000000000000000000001m).ToString (), "27");
1437                         Assert.AreEqual ("0.0000000000000000000000000001", (0.0000000000000000000000000001m).ToString (), "28");
1438                 }
1439
1440                 [Test]
1441                 public void MidpointRoundingAwayFromZero ()
1442                 {
1443                         MidpointRounding m = MidpointRounding.AwayFromZero;
1444                         Assert.AreEqual (4, Math.Round (3.5M, m), "#1");
1445                         Assert.AreEqual (3, Math.Round (2.8M, m), "#2");
1446                         Assert.AreEqual (3, Math.Round (2.5M, m), "#3");
1447                         Assert.AreEqual (2, Math.Round (2.1M, m), "#4");
1448                         Assert.AreEqual (-2, Math.Round (-2.1M, m), "#5");
1449                         Assert.AreEqual (-3, Math.Round (-2.5M, m), "#6");
1450                         Assert.AreEqual (-3, Math.Round (-2.8M, m), "#7");
1451                         Assert.AreEqual (-4, Math.Round (-3.5M, m), "#8");
1452
1453                         Assert.AreEqual (3.1M, Math.Round (3.05M, 1, m), "#9");
1454                         Assert.AreEqual (2.1M, Math.Round (2.08M, 1, m), "#10");
1455                         Assert.AreEqual (2.1M, Math.Round (2.05M, 1, m), "#11");
1456                         Assert.AreEqual (2.0M, Math.Round (2.01M, 1, m), "#12");
1457                         Assert.AreEqual (-2.0M, Math.Round (-2.01M, 1, m), "#13");
1458                         Assert.AreEqual (-2.1M, Math.Round (-2.05M, 1, m), "#14");
1459                         Assert.AreEqual (-2.1M, Math.Round (-2.08M, 1, m), "#15");
1460                         Assert.AreEqual (-3.1M, Math.Round (-3.05M, 1, m), "#16");
1461                 }
1462
1463                 [Test] // bug #4814
1464                 [SetCulture("")]
1465                 public void Parse_NumberGroupSeparatorIsEmpty_DoNotThrowIndexOutOfRangeException ()
1466                 {
1467                         NumberFormatInfo nf = new NumberFormatInfo ();
1468                         nf.NumberGroupSeparator = "";
1469                         Decimal.Parse ("1.5", nf);
1470                 }
1471
1472                 [Test] // bug #4814
1473                 [SetCulture("")]
1474                 public void Parse_CurrencyGroupSeparatorIsEmpty_DoNotThrowIndexOutOfRangeException ()
1475                 {
1476                         NumberFormatInfo nf = new NumberFormatInfo ();
1477                         nf.CurrencyGroupSeparator = "";
1478                         Decimal.Parse ("\u00A41.5", NumberStyles.Currency, nf);
1479                 }
1480
1481                 [Test] // bug #4814
1482                 [SetCulture("")]
1483                 public void Parse_LeadingSign_PositiveSignIsEmpty_DoNotThrowIndexOutOfRangeException ()
1484                 {
1485                         NumberFormatInfo nf = new NumberFormatInfo ();
1486                         nf.PositiveSign = "";
1487                         try {
1488                                 Decimal.Parse ("+15", nf);
1489                         } catch (FormatException) {
1490                                 return;
1491                         }
1492
1493                         Assert.Fail ("Expected FormatException");
1494                 }
1495
1496                 [Test] // bug #4814
1497                 [SetCulture("")]
1498                 public void Parse_LeadingSign_NegativeSignIsEmpty_DoNotThrowIndexOutOfRangeException ()
1499                 {
1500                         NumberFormatInfo nf = new NumberFormatInfo ();
1501                         nf.NegativeSign = "";
1502                         try {
1503                                 Decimal.Parse ("-15", nf);
1504                         } catch (FormatException) {
1505                                 return;
1506                         }
1507
1508                         Assert.Fail ("Expected FormatException");
1509                 }
1510
1511                 [Test] // bug #4814
1512                 [SetCulture("")]
1513                 public void Parse_TrailingSign_PositiveSignIsEmpty_DoNotThrowIndexOutOfRangeException ()
1514                 {
1515                         NumberFormatInfo nf = new NumberFormatInfo ();
1516                         nf.PositiveSign = "";
1517                         try {
1518                                 Decimal.Parse ("15+", nf);
1519                         } catch (FormatException) {
1520                                 return;
1521                         }
1522
1523                         Assert.Fail ("Expected FormatException");
1524                 }
1525
1526                 [Test] // bug #4814
1527                 [SetCulture("")]
1528                 public void Parse_TrailingSign_NegativeSignIsEmpty_DoNotThrowIndexOutOfRangeException ()
1529                 {
1530                         NumberFormatInfo nf = new NumberFormatInfo ();
1531                         nf.NegativeSign = "";
1532                         try {
1533                                 Decimal.Parse ("15-", nf);
1534                         } catch (FormatException) {
1535                                 return;
1536                         }
1537
1538                         Assert.Fail ("Expected FormatException");
1539                 }
1540
1541                 [Test]
1542                 [SetCulture("en-US")]
1543                 public void ParseZeros ()
1544                 {
1545                         var d = Decimal.Parse ("0.000");
1546                         var bits = Decimal.GetBits (d);
1547                         Assert.AreEqual (0, bits[0], "#1");
1548                         Assert.AreEqual (0, bits[1], "#2");
1549                         Assert.AreEqual (0, bits[2], "#3");
1550                         Assert.AreEqual (196608, bits[3], "#4");
1551                         Assert.AreEqual ("0.000", d.ToString (), "#5");
1552
1553                         d = Decimal.Parse("0.000000000000000000000000000000000000000000000000000000000000000000");
1554                         Assert.AreEqual ("0.0000000000000000000000000000", d.ToString (), "#10");
1555
1556                         d = Decimal.Parse ("0.");
1557                         Assert.AreEqual ("0", d.ToString (), "#11");
1558                 }
1559
1560                 [Test] // bug #21764
1561                 public void RoundToString ()
1562                 {
1563                         Assert.AreEqual ("3", Math.Round (3M, 5).ToString (CultureInfo.InvariantCulture), "#1");
1564                         Assert.AreEqual ("3.01", Math.Round (3.01M, 5).ToString (CultureInfo.InvariantCulture), "#2");
1565                         Assert.AreEqual ("-3.01", Math.Round (-3.01M, 5).ToString (CultureInfo.InvariantCulture), "#3");
1566                         Assert.AreEqual ("128", Math.Round (127.5M, 0).ToString (CultureInfo.InvariantCulture), "#4");
1567                 }
1568
1569                 [Test] // Bug Xamarin#14822
1570                 public void RoundToString_Bug14822 ()
1571                 {
1572                         decimal value = 1.600000m;
1573                         var roundedValue = Math.Round (value, 3);
1574                         Assert.AreEqual ("1.600", roundedValue.ToString (), "#1");
1575                 }
1576
1577                 [Test] // Bug Xamarin#17538
1578                 public void BankerRounding ()
1579                 {
1580                         decimal dcm3 = 987654321098765432109876543.2m;
1581                         decimal dcm4 = 0.05m;
1582                         decimal dcm5 = dcm3 + dcm4;
1583
1584                         Assert.AreEqual (987654321098765432109876543.2m, dcm5);
1585                 }
1586
1587                 [Test] // Bug Xamarin #24411
1588                 [Category ("MobileNotWorking")] // Bug Xamarin #27269
1589                 public void DecimalDivision_24411  ()
1590                 {
1591                         decimal dd = 45m;
1592                         var x = dd / 100;
1593                         var bits = decimal.GetBits (x);
1594                         var flags = (uint) bits[3];
1595                         byte scale2 = (byte)(flags >> 16);
1596                         
1597                         Assert.AreEqual (2, scale2);
1598
1599                         // The side effect is that 45m/100 should render as 0.45, not 0.4500000000000000000000000000
1600                         // Just for completeness:
1601
1602                         Assert.AreEqual ("0.45", (45m/100).ToString ());
1603                 }
1604
1605                 [Test] // Bug SUSE #655780
1606                 [Category ("MobileNotWorking")] // Bug Xamarin #27269
1607                 public void TrailingZerosBug ()
1608                 {
1609                         decimal d;
1610                         Assert.AreEqual ("0", (0m/5).ToString ());
1611                         Assert.AreEqual ("0.2", (1m/5).ToString ());
1612                         Assert.AreEqual ("0.4", (2m/5).ToString ());
1613                         Assert.AreEqual ("0.6", (3m/5).ToString ());
1614                         Assert.AreEqual ("0.8", (4m/5).ToString ());
1615                 }
1616         }
1617 }