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