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