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