1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.tests.java.math;
19
20import java.io.ByteArrayInputStream;
21import java.io.ByteArrayOutputStream;
22import java.io.ObjectInputStream;
23import java.io.ObjectOutputStream;
24import java.math.BigDecimal;
25import java.math.BigInteger;
26import java.math.MathContext;
27import java.math.RoundingMode;
28
29
30public class BigDecimalTest extends junit.framework.TestCase {
31	BigInteger value = new BigInteger("12345908");
32
33	BigInteger value2 = new BigInteger("12334560000");
34
35	/**
36	 * @tests java.math.BigDecimal#BigDecimal(java.math.BigInteger)
37	 */
38	public void test_ConstructorLjava_math_BigInteger() {
39		BigDecimal big = new BigDecimal(value);
40		assertTrue("the BigDecimal value is not initialized properly", big
41				.unscaledValue().equals(value)
42				&& big.scale() == 0);
43	}
44
45	/**
46	 * @tests java.math.BigDecimal#BigDecimal(java.math.BigInteger, int)
47	 */
48	public void test_ConstructorLjava_math_BigIntegerI() {
49		BigDecimal big = new BigDecimal(value2, 5);
50		assertTrue("the BigDecimal value is not initialized properly", big
51				.unscaledValue().equals(value2)
52				&& big.scale() == 5);
53		assertTrue("the BigDecimal value is not represented properly", big
54				.toString().equals("123345.60000"));
55	}
56
57	/**
58	 * @tests java.math.BigDecimal#BigDecimal(double)
59	 */
60	public void test_ConstructorD() {
61		BigDecimal big = new BigDecimal(123E04);
62		assertTrue(
63				"the BigDecimal value taking a double argument is not initialized properly",
64				big.toString().equals("1230000"));
65		big = new BigDecimal(1.2345E-12);
66		assertTrue("the double representation is not correct", big
67				.doubleValue() == 1.2345E-12);
68		big = new BigDecimal(-12345E-3);
69		assertTrue("the double representation is not correct", big
70				.doubleValue() == -12.345);
71		big = new BigDecimal(5.1234567897654321e138);
72		assertTrue("the double representation is not correct", big
73				.doubleValue() == 5.1234567897654321E138
74				&& big.scale() == 0);
75		big = new BigDecimal(0.1);
76		assertTrue(
77				"the double representation of 0.1 bigDecimal is not correct",
78				big.doubleValue() == 0.1);
79		big = new BigDecimal(0.00345);
80		assertTrue(
81				"the double representation of 0.00345 bigDecimal is not correct",
82				big.doubleValue() == 0.00345);
83        // regression test for HARMONY-2429
84        big = new BigDecimal(-0.0);
85        assertTrue(
86        		"the double representation of -0.0 bigDecimal is not correct",
87        		big.scale() == 0);
88	}
89
90	/**
91	 * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
92	 */
93	public void test_ConstructorLjava_lang_String() throws NumberFormatException {
94		BigDecimal big = new BigDecimal("345.23499600293850");
95		assertTrue("the BigDecimal value is not initialized properly", big
96				.toString().equals("345.23499600293850")
97				&& big.scale() == 14);
98		big = new BigDecimal("-12345");
99		assertTrue("the BigDecimal value is not initialized properly", big
100				.toString().equals("-12345")
101				&& big.scale() == 0);
102		big = new BigDecimal("123.");
103		assertTrue("the BigDecimal value is not initialized properly", big
104				.toString().equals("123")
105				&& big.scale() == 0);
106
107		new BigDecimal("1.234E02");
108	}
109
110	/**
111	 * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
112	 */
113	public void test_constructor_String_plus_exp() {
114		/*
115		 * BigDecimal does not support a + sign in the exponent when converting
116		 * from a String
117		 */
118		new BigDecimal(+23e-0);
119		new BigDecimal(-23e+0);
120	}
121
122	/**
123	 * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
124	 */
125	public void test_constructor_String_empty() {
126		try {
127			new BigDecimal("");
128            fail("NumberFormatException expected");
129		} catch (NumberFormatException e) {
130		}
131	}
132
133	/**
134	 * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
135	 */
136	public void test_constructor_String_plus_minus_exp() {
137		try {
138			new BigDecimal("+35e+-2");
139            fail("NumberFormatException expected");
140		} catch (NumberFormatException e) {
141		}
142
143		try {
144			new BigDecimal("-35e-+2");
145            fail("NumberFormatException expected");
146		} catch (NumberFormatException e) {
147		}
148	}
149
150    /**
151     * @tests java.math.BigDecimal#BigDecimal(char[])
152     */
153    public void test_constructor_CC_plus_minus_exp() {
154        try {
155            new BigDecimal("+35e+-2".toCharArray());
156            fail("NumberFormatException expected");
157        } catch (NumberFormatException e) {
158        }
159
160        try {
161            new BigDecimal("-35e-+2".toCharArray());
162            fail("NumberFormatException expected");
163        } catch (NumberFormatException e) {
164        }
165    }
166
167	/**
168	 * @tests java.math.BigDecimal#abs()
169	 */
170	public void test_abs() {
171		BigDecimal big = new BigDecimal("-1234");
172		BigDecimal bigabs = big.abs();
173		assertTrue("the absolute value of -1234 is not 1234", bigabs.toString()
174				.equals("1234"));
175		big = new BigDecimal(new BigInteger("2345"), 2);
176		bigabs = big.abs();
177		assertTrue("the absolute value of 23.45 is not 23.45", bigabs
178				.toString().equals("23.45"));
179	}
180
181	/**
182	 * @tests java.math.BigDecimal#add(java.math.BigDecimal)
183	 */
184	public void test_addLjava_math_BigDecimal() {
185		BigDecimal add1 = new BigDecimal("23.456");
186		BigDecimal add2 = new BigDecimal("3849.235");
187		BigDecimal sum = add1.add(add2);
188		assertTrue("the sum of 23.456 + 3849.235 is wrong", sum.unscaledValue()
189				.toString().equals("3872691")
190				&& sum.scale() == 3);
191		assertTrue("the sum of 23.456 + 3849.235 is not printed correctly", sum
192				.toString().equals("3872.691"));
193		BigDecimal add3 = new BigDecimal(12.34E02D);
194		assertTrue("the sum of 23.456 + 12.34E02 is not printed correctly",
195				(add1.add(add3)).toString().equals("1257.456"));
196	}
197
198	/**
199	 * @tests java.math.BigDecimal#compareTo(java.math.BigDecimal)
200	 */
201	public void test_compareToLjava_math_BigDecimal() {
202		BigDecimal comp1 = new BigDecimal("1.00");
203		BigDecimal comp2 = new BigDecimal(1.000000D);
204		assertTrue("1.00 and 1.000000 should be equal",
205				comp1.compareTo(comp2) == 0);
206		BigDecimal comp3 = new BigDecimal("1.02");
207		assertTrue("1.02 should be bigger than 1.00",
208				comp3.compareTo(comp1) == 1);
209		BigDecimal comp4 = new BigDecimal(0.98D);
210		assertTrue("0.98 should be less than 1.00",
211				comp4.compareTo(comp1) == -1);
212	}
213
214	/**
215	 * @tests java.math.BigDecimal#divide(java.math.BigDecimal, int)
216	 */
217	public void test_divideLjava_math_BigDecimalI() {
218		BigDecimal divd1 = new BigDecimal(value, 2);
219		BigDecimal divd2 = new BigDecimal("2.335");
220		BigDecimal divd3 = divd1.divide(divd2, BigDecimal.ROUND_UP);
221		assertTrue("123459.08/2.335 is not correct", divd3.toString().equals(
222				"52873.27")
223				&& divd3.scale() == divd1.scale());
224		assertTrue(
225				"the unscaledValue representation of 123459.08/2.335 is not correct",
226				divd3.unscaledValue().toString().equals("5287327"));
227		divd2 = new BigDecimal(123.4D);
228		divd3 = divd1.divide(divd2, BigDecimal.ROUND_DOWN);
229		assertTrue("123459.08/123.4  is not correct", divd3.toString().equals(
230				"1000.47")
231				&& divd3.scale() == 2);
232		divd2 = new BigDecimal(000D);
233
234		try {
235			divd1.divide(divd2, BigDecimal.ROUND_DOWN);
236            fail("divide by zero is not caught");
237		} catch (ArithmeticException e) {
238		}
239	}
240
241	/**
242	 * @tests java.math.BigDecimal#divide(java.math.BigDecimal, int, int)
243	 */
244	public void test_divideLjava_math_BigDecimalII() {
245		BigDecimal divd1 = new BigDecimal(value2, 4);
246		BigDecimal divd2 = new BigDecimal("0.0023");
247		BigDecimal divd3 = divd1.divide(divd2, 3, BigDecimal.ROUND_HALF_UP);
248		assertTrue("1233456/0.0023 is not correct", divd3.toString().equals(
249				"536285217.391")
250				&& divd3.scale() == 3);
251		divd2 = new BigDecimal(1345.5E-02D);
252		divd3 = divd1.divide(divd2, 0, BigDecimal.ROUND_DOWN);
253		assertTrue(
254				"1233456/13.455 is not correct or does not have the correct scale",
255				divd3.toString().equals("91672") && divd3.scale() == 0);
256		divd2 = new BigDecimal(0000D);
257
258		try {
259			divd1.divide(divd2, 4, BigDecimal.ROUND_DOWN);
260            fail("divide by zero is not caught");
261		} catch (ArithmeticException e) {
262		}
263	}
264
265	/**
266	 * @tests java.math.BigDecimal#doubleValue()
267	 */
268	public void test_doubleValue() {
269		BigDecimal bigDB = new BigDecimal(-1.234E-112);
270//		Commenting out this part because it causes an endless loop (see HARMONY-319 and HARMONY-329)
271//		assertTrue(
272//				"the double representation of this BigDecimal is not correct",
273//				bigDB.doubleValue() == -1.234E-112);
274		bigDB = new BigDecimal(5.00E-324);
275		assertTrue("the double representation of bigDecimal is not correct",
276				bigDB.doubleValue() == 5.00E-324);
277		bigDB = new BigDecimal(1.79E308);
278		assertTrue("the double representation of bigDecimal is not correct",
279				bigDB.doubleValue() == 1.79E308 && bigDB.scale() == 0);
280		bigDB = new BigDecimal(-2.33E102);
281		assertTrue(
282				"the double representation of bigDecimal -2.33E102 is not correct",
283				bigDB.doubleValue() == -2.33E102 && bigDB.scale() == 0);
284		bigDB = new BigDecimal(Double.MAX_VALUE);
285		bigDB = bigDB.add(bigDB);
286		assertTrue(
287				"a  + number out of the double range should return infinity",
288				bigDB.doubleValue() == Double.POSITIVE_INFINITY);
289		bigDB = new BigDecimal(-Double.MAX_VALUE);
290		bigDB = bigDB.add(bigDB);
291		assertTrue(
292				"a  - number out of the double range should return neg infinity",
293				bigDB.doubleValue() == Double.NEGATIVE_INFINITY);
294	}
295
296	/**
297	 * @tests java.math.BigDecimal#equals(java.lang.Object)
298	 */
299	public void test_equalsLjava_lang_Object() {
300		BigDecimal equal1 = new BigDecimal(1.00D);
301		BigDecimal equal2 = new BigDecimal("1.0");
302		assertFalse("1.00 and 1.0 should not be equal",
303				equal1.equals(equal2));
304		equal2 = new BigDecimal(1.01D);
305		assertFalse("1.00 and 1.01 should not be equal",
306				equal1.equals(equal2));
307		equal2 = new BigDecimal("1.00");
308		assertFalse("1.00D and 1.00 should not be equal",
309				equal1.equals(equal2));
310		BigInteger val = new BigInteger("100");
311		equal1 = new BigDecimal("1.00");
312		equal2 = new BigDecimal(val, 2);
313		assertTrue("1.00(string) and 1.00(bigInteger) should be equal", equal1
314				.equals(equal2));
315		equal1 = new BigDecimal(100D);
316		equal2 = new BigDecimal("2.34576");
317		assertFalse("100D and 2.34576 should not be equal", equal1
318				.equals(equal2));
319		assertFalse("bigDecimal 100D does not equal string 23415", equal1
320				.equals("23415"));
321	}
322
323	/**
324	 * @tests java.math.BigDecimal#floatValue()
325	 */
326	public void test_floatValue() {
327		BigDecimal fl1 = new BigDecimal("234563782344567");
328		assertTrue("the float representation of bigDecimal 234563782344567",
329				fl1.floatValue() == 234563782344567f);
330		BigDecimal fl2 = new BigDecimal(2.345E37);
331		assertTrue("the float representation of bigDecimal 2.345E37", fl2
332				.floatValue() == 2.345E37F);
333		fl2 = new BigDecimal(-1.00E-44);
334		assertTrue("the float representation of bigDecimal -1.00E-44", fl2
335				.floatValue() == -1.00E-44F);
336		fl2 = new BigDecimal(-3E12);
337		assertTrue("the float representation of bigDecimal -3E12", fl2
338				.floatValue() == -3E12F);
339		fl2 = new BigDecimal(Double.MAX_VALUE);
340		assertTrue(
341				"A number can't be represented by float should return infinity",
342				fl2.floatValue() == Float.POSITIVE_INFINITY);
343		fl2 = new BigDecimal(-Double.MAX_VALUE);
344		assertTrue(
345				"A number can't be represented by float should return infinity",
346				fl2.floatValue() == Float.NEGATIVE_INFINITY);
347
348	}
349
350	/**
351	 * @tests java.math.BigDecimal#hashCode()
352	 */
353	public void test_hashCode() {
354		// anything that is equal must have the same hashCode
355		BigDecimal hash = new BigDecimal("1.00");
356		BigDecimal hash2 = new BigDecimal(1.00D);
357		assertTrue("the hashCode of 1.00 and 1.00D is equal",
358				hash.hashCode() != hash2.hashCode() && !hash.equals(hash2));
359		hash2 = new BigDecimal("1.0");
360		assertTrue("the hashCode of 1.0 and 1.00 is equal",
361				hash.hashCode() != hash2.hashCode() && !hash.equals(hash2));
362		BigInteger val = new BigInteger("100");
363		hash2 = new BigDecimal(val, 2);
364		assertTrue("hashCode of 1.00 and 1.00(bigInteger) is not equal", hash
365				.hashCode() == hash2.hashCode()
366				&& hash.equals(hash2));
367		hash = new BigDecimal(value, 2);
368		hash2 = new BigDecimal("-1233456.0000");
369		assertTrue("hashCode of 123459.08 and -1233456.0000 is not equal", hash
370				.hashCode() != hash2.hashCode()
371				&& !hash.equals(hash2));
372		hash2 = new BigDecimal(value.negate(), 2);
373		assertTrue("hashCode of 123459.08 and -123459.08 is not equal", hash
374				.hashCode() != hash2.hashCode()
375				&& !hash.equals(hash2));
376	}
377
378	/**
379	 * @tests java.math.BigDecimal#intValue()
380	 */
381	public void test_intValue() {
382		BigDecimal int1 = new BigDecimal(value, 3);
383		assertTrue("the int value of 12345.908 is not 12345",
384				int1.intValue() == 12345);
385		int1 = new BigDecimal("1.99");
386		assertTrue("the int value of 1.99 is not 1", int1.intValue() == 1);
387		int1 = new BigDecimal("23423419083091823091283933");
388		// ran JDK and found representation for the above was -249268259
389		assertTrue("the int value of 23423419083091823091283933 is wrong", int1
390				.intValue() == -249268259);
391		int1 = new BigDecimal(-1235D);
392		assertTrue("the int value of -1235 is not -1235",
393				int1.intValue() == -1235);
394	}
395
396	/**
397	 * @tests java.math.BigDecimal#longValue()
398	 */
399	public void test_longValue() {
400		BigDecimal long1 = new BigDecimal(value2.negate(), 0);
401		assertTrue("the long value of 12334560000 is not 12334560000", long1
402				.longValue() == -12334560000L);
403		long1 = new BigDecimal(-1345.348E-123D);
404		assertTrue("the long value of -1345.348E-123D is not zero", long1
405				.longValue() == 0);
406		long1 = new BigDecimal("31323423423419083091823091283933");
407		// ran JDK and found representation for the above was
408		// -5251313250005125155
409		assertTrue(
410				"the long value of 31323423423419083091823091283933 is wrong",
411				long1.longValue() == -5251313250005125155L);
412	}
413
414	/**
415	 * @tests java.math.BigDecimal#max(java.math.BigDecimal)
416	 */
417	public void test_maxLjava_math_BigDecimal() {
418		BigDecimal max1 = new BigDecimal(value2, 1);
419		BigDecimal max2 = new BigDecimal(value2, 4);
420		assertTrue("1233456000.0 is not greater than 1233456", max1.max(max2)
421				.equals(max1));
422		max1 = new BigDecimal(-1.224D);
423		max2 = new BigDecimal(-1.2245D);
424		assertTrue("-1.224 is not greater than -1.2245", max1.max(max2).equals(
425				max1));
426		max1 = new BigDecimal(123E18);
427		max2 = new BigDecimal(123E19);
428		assertTrue("123E19 is the not the max", max1.max(max2).equals(max2));
429	}
430
431	/**
432	 * @tests java.math.BigDecimal#min(java.math.BigDecimal)
433	 */
434	public void test_minLjava_math_BigDecimal() {
435		BigDecimal min1 = new BigDecimal(-12345.4D);
436		BigDecimal min2 = new BigDecimal(-12345.39D);
437		assertTrue("-12345.39 should have been returned", min1.min(min2)
438				.equals(min1));
439		min1 = new BigDecimal(value2, 5);
440		min2 = new BigDecimal(value2, 0);
441		assertTrue("123345.6 should have been returned", min1.min(min2).equals(
442				min1));
443	}
444
445	/**
446	 * @tests java.math.BigDecimal#movePointLeft(int)
447	 */
448	public void test_movePointLeftI() {
449		BigDecimal movePtLeft = new BigDecimal("123456265.34");
450		BigDecimal alreadyMoved = movePtLeft.movePointLeft(5);
451		assertTrue("move point left 5 failed", alreadyMoved.scale() == 7
452				&& alreadyMoved.toString().equals("1234.5626534"));
453		movePtLeft = new BigDecimal(value2.negate(), 0);
454		alreadyMoved = movePtLeft.movePointLeft(12);
455		assertTrue("move point left 12 failed", alreadyMoved.scale() == 12
456				&& alreadyMoved.toString().equals("-0.012334560000"));
457		movePtLeft = new BigDecimal(123E18);
458		alreadyMoved = movePtLeft.movePointLeft(2);
459		assertTrue("move point left 2 failed",
460				alreadyMoved.scale() == movePtLeft.scale() + 2
461						&& alreadyMoved.doubleValue() == 1.23E18);
462		movePtLeft = new BigDecimal(1.123E-12);
463		alreadyMoved = movePtLeft.movePointLeft(3);
464		assertTrue("move point left 3 failed",
465				alreadyMoved.scale() == movePtLeft.scale() + 3
466						&& alreadyMoved.doubleValue() == 1.123E-15);
467		movePtLeft = new BigDecimal(value, 2);
468		alreadyMoved = movePtLeft.movePointLeft(-2);
469		assertTrue("move point left -2 failed",
470				alreadyMoved.scale() == movePtLeft.scale() - 2
471						&& alreadyMoved.toString().equals("12345908"));
472	}
473
474	/**
475	 * @tests java.math.BigDecimal#movePointRight(int)
476	 */
477	public void test_movePointRightI() {
478		BigDecimal movePtRight = new BigDecimal("-1.58796521458");
479		BigDecimal alreadyMoved = movePtRight.movePointRight(8);
480		assertTrue("move point right 8 failed", alreadyMoved.scale() == 3
481				&& alreadyMoved.toString().equals("-158796521.458"));
482		movePtRight = new BigDecimal(value, 2);
483		alreadyMoved = movePtRight.movePointRight(4);
484		assertTrue("move point right 4 failed", alreadyMoved.scale() == 0
485				&& alreadyMoved.toString().equals("1234590800"));
486		movePtRight = new BigDecimal(134E12);
487		alreadyMoved = movePtRight.movePointRight(2);
488		assertTrue("move point right 2 failed", alreadyMoved.scale() == 0
489				&& alreadyMoved.toString().equals("13400000000000000"));
490		movePtRight = new BigDecimal(-3.4E-10);
491		alreadyMoved = movePtRight.movePointRight(5);
492		assertTrue("move point right 5 failed",
493				alreadyMoved.scale() == movePtRight.scale() - 5
494						&& alreadyMoved.doubleValue() == -0.000034);
495		alreadyMoved = alreadyMoved.movePointRight(-5);
496		assertTrue("move point right -5 failed", alreadyMoved
497				.equals(movePtRight));
498	}
499
500	/**
501	 * @tests java.math.BigDecimal#multiply(java.math.BigDecimal)
502	 */
503	public void test_multiplyLjava_math_BigDecimal() {
504		BigDecimal multi1 = new BigDecimal(value, 5);
505		BigDecimal multi2 = new BigDecimal(2.345D);
506		BigDecimal result = multi1.multiply(multi2);
507		assertTrue("123.45908 * 2.345 is not correct: " + result, result
508				.toString().startsWith("289.51154260")
509				&& result.scale() == multi1.scale() + multi2.scale());
510		multi1 = new BigDecimal("34656");
511		multi2 = new BigDecimal("-2");
512		result = multi1.multiply(multi2);
513		assertTrue("34656 * 2 is not correct", result.toString().equals(
514				"-69312")
515				&& result.scale() == 0);
516		multi1 = new BigDecimal(-2.345E-02);
517		multi2 = new BigDecimal(-134E130);
518		result = multi1.multiply(multi2);
519		assertTrue("-2.345E-02 * -134E130 is not correct " + result.doubleValue(),
520				result.doubleValue() == 3.1422999999999997E130
521						&& result.scale() == multi1.scale() + multi2.scale());
522		multi1 = new BigDecimal("11235");
523		multi2 = new BigDecimal("0");
524		result = multi1.multiply(multi2);
525		assertTrue("11235 * 0 is not correct", result.doubleValue() == 0
526				&& result.scale() == 0);
527		multi1 = new BigDecimal("-0.00234");
528		multi2 = new BigDecimal(13.4E10);
529		result = multi1.multiply(multi2);
530		assertTrue("-0.00234 * 13.4E10 is not correct",
531				result.doubleValue() == -313560000
532						&& result.scale() == multi1.scale() + multi2.scale());
533	}
534
535	/**
536	 * @tests java.math.BigDecimal#negate()
537	 */
538	public void test_negate() {
539		BigDecimal negate1 = new BigDecimal(value2, 7);
540		assertTrue("the negate of 1233.4560000 is not -1233.4560000", negate1
541				.negate().toString().equals("-1233.4560000"));
542		negate1 = new BigDecimal("-23465839");
543		assertTrue("the negate of -23465839 is not 23465839", negate1.negate()
544				.toString().equals("23465839"));
545		negate1 = new BigDecimal(-3.456E6);
546		assertTrue("the negate of -3.456E6 is not 3.456E6", negate1.negate()
547				.negate().equals(negate1));
548	}
549
550	/**
551	 * @tests java.math.BigDecimal#scale()
552	 */
553	public void test_scale() {
554		BigDecimal scale1 = new BigDecimal(value2, 8);
555		assertTrue("the scale of the number 123.34560000 is wrong", scale1
556				.scale() == 8);
557		BigDecimal scale2 = new BigDecimal("29389.");
558		assertTrue("the scale of the number 29389. is wrong",
559				scale2.scale() == 0);
560		BigDecimal scale3 = new BigDecimal(3.374E13);
561		assertTrue("the scale of the number 3.374E13 is wrong",
562				scale3.scale() == 0);
563		BigDecimal scale4 = new BigDecimal("-3.45E-203");
564		// note the scale is calculated as 15 digits of 345000.... + exponent -
565		// 1. -1 for the 3
566		assertTrue("the scale of the number -3.45E-203 is wrong: "
567				+ scale4.scale(), scale4.scale() == 205);
568		scale4 = new BigDecimal("-345.4E-200");
569		assertTrue("the scale of the number -345.4E-200 is wrong", scale4
570				.scale() == 201);
571	}
572
573	/**
574	 * @tests java.math.BigDecimal#setScale(int)
575	 */
576	public void test_setScaleI() {
577		// rounding mode defaults to zero
578		BigDecimal setScale1 = new BigDecimal(value, 3);
579		BigDecimal setScale2 = setScale1.setScale(5);
580		BigInteger setresult = new BigInteger("1234590800");
581		assertTrue("the number 12345.908 after setting scale is wrong",
582				setScale2.unscaledValue().equals(setresult)
583						&& setScale2.scale() == 5);
584
585		try {
586			setScale2 = setScale1.setScale(2, BigDecimal.ROUND_UNNECESSARY);
587            fail("arithmetic Exception not caught as a result of loosing precision");
588		} catch (ArithmeticException e) {
589		}
590	}
591
592	/**
593	 * @tests java.math.BigDecimal#setScale(int, int)
594	 */
595	public void test_setScaleII() {
596		BigDecimal setScale1 = new BigDecimal(2.323E102);
597		BigDecimal setScale2 = setScale1.setScale(4);
598		assertTrue("the number 2.323E102 after setting scale is wrong",
599				setScale2.scale() == 4);
600		assertTrue("the representation of the number 2.323E102 is wrong",
601				setScale2.doubleValue() == 2.323E102);
602		setScale1 = new BigDecimal("-1.253E-12");
603		setScale2 = setScale1.setScale(17, BigDecimal.ROUND_CEILING);
604		assertTrue("the number -1.253E-12 after setting scale is wrong",
605				setScale2.scale() == 17);
606		assertTrue(
607				"the representation of the number -1.253E-12 after setting scale is wrong, " + setScale2.toString(),
608				setScale2.toString().equals("-1.25300E-12"));
609
610		// testing rounding Mode ROUND_CEILING
611		setScale1 = new BigDecimal(value, 4);
612		setScale2 = setScale1.setScale(1, BigDecimal.ROUND_CEILING);
613		assertTrue(
614				"the number 1234.5908 after setting scale to 1/ROUND_CEILING is wrong",
615				setScale2.toString().equals("1234.6") && setScale2.scale() == 1);
616		BigDecimal setNeg = new BigDecimal(value.negate(), 4);
617		setScale2 = setNeg.setScale(1, BigDecimal.ROUND_CEILING);
618		assertTrue(
619				"the number -1234.5908 after setting scale to 1/ROUND_CEILING is wrong",
620				setScale2.toString().equals("-1234.5")
621						&& setScale2.scale() == 1);
622
623		// testing rounding Mode ROUND_DOWN
624		setScale2 = setNeg.setScale(1, BigDecimal.ROUND_DOWN);
625		assertTrue(
626				"the number -1234.5908 after setting scale to 1/ROUND_DOWN is wrong",
627				setScale2.toString().equals("-1234.5")
628						&& setScale2.scale() == 1);
629		setScale1 = new BigDecimal(value, 4);
630		setScale2 = setScale1.setScale(1, BigDecimal.ROUND_DOWN);
631		assertTrue(
632				"the number 1234.5908 after setting scale to 1/ROUND_DOWN is wrong",
633				setScale2.toString().equals("1234.5") && setScale2.scale() == 1);
634
635		// testing rounding Mode ROUND_FLOOR
636		setScale2 = setScale1.setScale(1, BigDecimal.ROUND_FLOOR);
637		assertTrue(
638				"the number 1234.5908 after setting scale to 1/ROUND_FLOOR is wrong",
639				setScale2.toString().equals("1234.5") && setScale2.scale() == 1);
640		setScale2 = setNeg.setScale(1, BigDecimal.ROUND_FLOOR);
641		assertTrue(
642				"the number -1234.5908 after setting scale to 1/ROUND_FLOOR is wrong",
643				setScale2.toString().equals("-1234.6")
644						&& setScale2.scale() == 1);
645
646		// testing rounding Mode ROUND_HALF_DOWN
647		setScale2 = setScale1.setScale(3, BigDecimal.ROUND_HALF_DOWN);
648		assertTrue(
649				"the number 1234.5908 after setting scale to 3/ROUND_HALF_DOWN is wrong",
650				setScale2.toString().equals("1234.591")
651						&& setScale2.scale() == 3);
652		setScale1 = new BigDecimal(new BigInteger("12345000"), 5);
653		setScale2 = setScale1.setScale(1, BigDecimal.ROUND_HALF_DOWN);
654		assertTrue(
655				"the number 123.45908 after setting scale to 1/ROUND_HALF_DOWN is wrong",
656				setScale2.toString().equals("123.4") && setScale2.scale() == 1);
657		setScale2 = new BigDecimal("-1234.5000").setScale(0,
658				BigDecimal.ROUND_HALF_DOWN);
659		assertTrue(
660				"the number -1234.5908 after setting scale to 0/ROUND_HALF_DOWN is wrong",
661				setScale2.toString().equals("-1234") && setScale2.scale() == 0);
662
663		// testing rounding Mode ROUND_HALF_EVEN
664		setScale1 = new BigDecimal(1.2345789D);
665		setScale2 = setScale1.setScale(4, BigDecimal.ROUND_HALF_EVEN);
666		assertTrue(
667				"the number 1.2345789 after setting scale to 4/ROUND_HALF_EVEN is wrong",
668				setScale2.doubleValue() == 1.2346D && setScale2.scale() == 4);
669		setNeg = new BigDecimal(-1.2335789D);
670		setScale2 = setNeg.setScale(2, BigDecimal.ROUND_HALF_EVEN);
671		assertTrue(
672				"the number -1.2335789 after setting scale to 2/ROUND_HALF_EVEN is wrong",
673				setScale2.doubleValue() == -1.23D && setScale2.scale() == 2);
674		setScale2 = new BigDecimal("1.2345000").setScale(3,
675				BigDecimal.ROUND_HALF_EVEN);
676		assertTrue(
677				"the number 1.2345789 after setting scale to 3/ROUND_HALF_EVEN is wrong",
678				setScale2.doubleValue() == 1.234D && setScale2.scale() == 3);
679		setScale2 = new BigDecimal("-1.2345000").setScale(3,
680				BigDecimal.ROUND_HALF_EVEN);
681		assertTrue(
682				"the number -1.2335789 after setting scale to 3/ROUND_HALF_EVEN is wrong",
683				setScale2.doubleValue() == -1.234D && setScale2.scale() == 3);
684
685		// testing rounding Mode ROUND_HALF_UP
686		setScale1 = new BigDecimal("134567.34650");
687		setScale2 = setScale1.setScale(3, BigDecimal.ROUND_HALF_UP);
688		assertTrue(
689				"the number 134567.34658 after setting scale to 3/ROUND_HALF_UP is wrong",
690				setScale2.toString().equals("134567.347")
691						&& setScale2.scale() == 3);
692		setNeg = new BigDecimal("-1234.4567");
693		setScale2 = setNeg.setScale(0, BigDecimal.ROUND_HALF_UP);
694		assertTrue(
695				"the number -1234.4567 after setting scale to 0/ROUND_HALF_UP is wrong",
696				setScale2.toString().equals("-1234") && setScale2.scale() == 0);
697
698		// testing rounding Mode ROUND_UNNECESSARY
699		try {
700			setScale1.setScale(3, BigDecimal.ROUND_UNNECESSARY);
701            fail("arithmetic Exception not caught for round unnecessary");
702		} catch (ArithmeticException e) {
703		}
704
705		// testing rounding Mode ROUND_UP
706		setScale1 = new BigDecimal("100000.374");
707		setScale2 = setScale1.setScale(2, BigDecimal.ROUND_UP);
708		assertTrue(
709				"the number 100000.374 after setting scale to 2/ROUND_UP is wrong",
710				setScale2.toString().equals("100000.38")
711						&& setScale2.scale() == 2);
712		setNeg = new BigDecimal(-134.34589D);
713		setScale2 = setNeg.setScale(2, BigDecimal.ROUND_UP);
714		assertTrue(
715				"the number -134.34589 after setting scale to 2/ROUND_UP is wrong",
716				setScale2.doubleValue() == -134.35D && setScale2.scale() == 2);
717
718		// testing invalid rounding modes
719		try {
720			setScale2 = setScale1.setScale(0, -123);
721            fail("IllegalArgumentException is not caught for wrong rounding mode");
722		} catch (IllegalArgumentException e) {
723		}
724	}
725
726	/**
727	 * @tests java.math.BigDecimal#signum()
728	 */
729	public void test_signum() {
730		BigDecimal sign = new BigDecimal(123E-104);
731		assertTrue("123E-104 is not positive in signum()", sign.signum() == 1);
732		sign = new BigDecimal("-1234.3959");
733		assertTrue("-1234.3959 is not negative in signum()",
734				sign.signum() == -1);
735		sign = new BigDecimal(000D);
736		assertTrue("000D is not zero in signum()", sign.signum() == 0);
737	}
738
739	/**
740	 * @tests java.math.BigDecimal#subtract(java.math.BigDecimal)
741	 */
742	public void test_subtractLjava_math_BigDecimal() {
743		BigDecimal sub1 = new BigDecimal("13948");
744		BigDecimal sub2 = new BigDecimal("2839.489");
745		BigDecimal result = sub1.subtract(sub2);
746		assertTrue("13948 - 2839.489 is wrong: " + result, result.toString()
747				.equals("11108.511")
748				&& result.scale() == 3);
749		BigDecimal result2 = sub2.subtract(sub1);
750		assertTrue("2839.489 - 13948 is wrong", result2.toString().equals(
751				"-11108.511")
752				&& result2.scale() == 3);
753		assertTrue("13948 - 2839.489 is not the negative of 2839.489 - 13948",
754				result.equals(result2.negate()));
755		sub1 = new BigDecimal(value, 1);
756		sub2 = new BigDecimal("0");
757		result = sub1.subtract(sub2);
758		assertTrue("1234590.8 - 0 is wrong", result.equals(sub1));
759		sub1 = new BigDecimal(1.234E-03);
760		sub2 = new BigDecimal(3.423E-10);
761		result = sub1.subtract(sub2);
762		assertTrue("1.234E-03 - 3.423E-10 is wrong, " + result.doubleValue(),
763				result.doubleValue() == 0.0012339996577);
764		sub1 = new BigDecimal(1234.0123);
765		sub2 = new BigDecimal(1234.0123000);
766		result = sub1.subtract(sub2);
767		assertTrue("1234.0123 - 1234.0123000 is wrong, " + result.doubleValue(),
768				result.doubleValue() == 0.0);
769	}
770
771	/**
772	 * @tests java.math.BigDecimal#toBigInteger()
773	 */
774	public void test_toBigInteger() {
775		BigDecimal sub1 = new BigDecimal("-29830.989");
776		BigInteger result = sub1.toBigInteger();
777
778		assertTrue("the bigInteger equivalent of -29830.989 is wrong", result
779				.toString().equals("-29830"));
780		sub1 = new BigDecimal(-2837E10);
781		result = sub1.toBigInteger();
782		assertTrue("the bigInteger equivalent of -2837E10 is wrong", result
783				.doubleValue() == -2837E10);
784		sub1 = new BigDecimal(2.349E-10);
785		result = sub1.toBigInteger();
786		assertTrue("the bigInteger equivalent of 2.349E-10 is wrong", result
787				.equals(BigInteger.ZERO));
788		sub1 = new BigDecimal(value2, 6);
789		result = sub1.toBigInteger();
790		assertTrue("the bigInteger equivalent of 12334.560000 is wrong", result
791				.toString().equals("12334"));
792	}
793
794	/**
795	 * @tests java.math.BigDecimal#toString()
796	 */
797	public void test_toString() {
798		BigDecimal toString1 = new BigDecimal("1234.000");
799		assertTrue("the toString representation of 1234.000 is wrong",
800				toString1.toString().equals("1234.000"));
801		toString1 = new BigDecimal("-123.4E-5");
802		assertTrue("the toString representation of -123.4E-5 is wrong: "
803				+ toString1, toString1.toString().equals("-0.001234"));
804		toString1 = new BigDecimal("-1.455E-20");
805		assertTrue("the toString representation of -1.455E-20 is wrong",
806				toString1.toString().equals("-1.455E-20"));
807		toString1 = new BigDecimal(value2, 4);
808		assertTrue("the toString representation of 1233456.0000 is wrong",
809				toString1.toString().equals("1233456.0000"));
810	}
811
812	/**
813	 * @tests java.math.BigDecimal#unscaledValue()
814	 */
815	public void test_unscaledValue() {
816		BigDecimal unsVal = new BigDecimal("-2839485.000");
817		assertTrue("the unscaledValue of -2839485.000 is wrong", unsVal
818				.unscaledValue().toString().equals("-2839485000"));
819		unsVal = new BigDecimal(123E10);
820		assertTrue("the unscaledValue of 123E10 is wrong", unsVal
821				.unscaledValue().toString().equals("1230000000000"));
822		unsVal = new BigDecimal("-4.56E-13");
823		assertTrue("the unscaledValue of -4.56E-13 is wrong: "
824				+ unsVal.unscaledValue(), unsVal.unscaledValue().toString()
825				.equals("-456"));
826		unsVal = new BigDecimal(value, 3);
827		assertTrue("the unscaledValue of 12345.908 is wrong", unsVal
828				.unscaledValue().toString().equals("12345908"));
829
830	}
831
832	/**
833	 * @tests java.math.BigDecimal#valueOf(long)
834	 */
835	public void test_valueOfJ() {
836		BigDecimal valueOfL = BigDecimal.valueOf(9223372036854775806L);
837		assertTrue("the bigDecimal equivalent of 9223372036854775806 is wrong",
838				valueOfL.unscaledValue().toString().equals(
839						"9223372036854775806")
840						&& valueOfL.scale() == 0);
841		assertTrue(
842				"the toString representation of 9223372036854775806 is wrong",
843				valueOfL.toString().equals("9223372036854775806"));
844		valueOfL = BigDecimal.valueOf(0L);
845		assertTrue("the bigDecimal equivalent of 0 is wrong", valueOfL
846				.unscaledValue().toString().equals("0")
847				&& valueOfL.scale() == 0);
848	}
849
850	/**
851	 * @tests java.math.BigDecimal#valueOf(long, int)
852	 */
853	public void test_valueOfJI() {
854		BigDecimal valueOfJI = BigDecimal.valueOf(9223372036854775806L, 5);
855		assertTrue(
856				"the bigDecimal equivalent of 92233720368547.75806 is wrong",
857				valueOfJI.unscaledValue().toString().equals(
858						"9223372036854775806")
859						&& valueOfJI.scale() == 5);
860		assertTrue(
861				"the toString representation of 9223372036854775806 is wrong",
862				valueOfJI.toString().equals("92233720368547.75806"));
863		valueOfJI = BigDecimal.valueOf(1234L, 8);
864		assertTrue(
865				"the bigDecimal equivalent of 92233720368547.75806 is wrong",
866				valueOfJI.unscaledValue().toString().equals("1234")
867						&& valueOfJI.scale() == 8);
868		assertTrue(
869				"the toString representation of 9223372036854775806 is wrong",
870				valueOfJI.toString().equals("0.00001234"));
871		valueOfJI = BigDecimal.valueOf(0, 3);
872		assertTrue(
873				"the bigDecimal equivalent of 92233720368547.75806 is wrong",
874				valueOfJI.unscaledValue().toString().equals("0")
875						&& valueOfJI.scale() == 3);
876		assertTrue(
877				"the toString representation of 9223372036854775806 is wrong",
878				valueOfJI.toString().equals("0.000"));
879
880	}
881
882	public void test_BigDecimal_serialization() throws Exception {
883        // Regression for HARMONY-1896
884        char[] in = { '1', '5', '6', '7', '8', '7', '.', '0', '0' };
885        BigDecimal bd = new BigDecimal(in, 0, 9);
886
887        ByteArrayOutputStream bos = new ByteArrayOutputStream();
888        ObjectOutputStream oos = new ObjectOutputStream(bos);
889        oos.writeObject(bd);
890
891        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
892        ObjectInputStream ois = new ObjectInputStream(bis);
893        BigDecimal nbd = (BigDecimal) ois.readObject();
894
895        assertEquals(bd.intValue(), nbd.intValue());
896        assertEquals(bd.doubleValue(), nbd.doubleValue(), 0.0);
897        assertEquals(bd.toString(), nbd.toString());
898    }
899
900	/**
901	 * @tests java.math.BigDecimal#stripTrailingZero(long)
902	 */
903	public void test_stripTrailingZero() {
904		BigDecimal sixhundredtest = new BigDecimal("600.0");
905		assertTrue("stripTrailingZero failed for 600.0",
906				((sixhundredtest.stripTrailingZeros()).scale() == -2)
907				);
908
909		/* Single digit, no trailing zero, odd number */
910		BigDecimal notrailingzerotest = new BigDecimal("1");
911		assertTrue("stripTrailingZero failed for 1",
912				((notrailingzerotest.stripTrailingZeros()).scale() == 0)
913				);
914
915                // BEGIN Android-changed: preserve RI compatibility, so BigDecimal.equals (which checks
916                // value *and* scale) continues to work. https://issues.apache.org/jira/browse/HARMONY-4623
917		/* Zero */
918		BigDecimal zerotest = new BigDecimal("0.0000");
919                assertEquals("stripTrailingZero failed for 0.0000", 4, zerotest.stripTrailingZeros().scale());
920	}
921
922	public void testMathContextConstruction() {
923        String a = "-12380945E+61";
924        BigDecimal aNumber = new BigDecimal(a);
925        int precision = 6;
926        RoundingMode rm = RoundingMode.HALF_DOWN;
927        MathContext mcIntRm = new MathContext(precision, rm);
928        MathContext mcStr = new MathContext("precision=6 roundingMode=HALF_DOWN");
929        MathContext mcInt = new MathContext(precision);
930        BigDecimal res = aNumber.abs(mcInt);
931        assertEquals("MathContext Constructer with int precision failed",
932                res,
933                new BigDecimal("1.23809E+68"));
934
935        assertEquals("Equal MathContexts are not Equal ",
936                mcIntRm,
937                mcStr);
938
939        assertEquals("Different MathContext are reported as Equal ",
940        		mcInt.equals(mcStr),
941                false);
942
943        assertEquals("Equal MathContexts have different hashcodes ",
944                mcIntRm.hashCode(),
945                mcStr.hashCode());
946
947        assertEquals("MathContext.toString() returning incorrect value",
948                mcIntRm.toString(),
949                "precision=6 roundingMode=HALF_DOWN");
950	}
951
952}
953