OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [math/] [BigDecimal.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* java.math.BigDecimal -- Arbitrary precision decimals.
2
   Copyright (C) 1999, 2000, 2001, 2003, 2005, 2006 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package java.math;
39
 
40
import gnu.java.lang.CPStringBuilder;
41
 
42
public class BigDecimal extends Number implements Comparable<BigDecimal>
43
{
44
  private BigInteger intVal;
45
  private int scale;
46
  private int precision = 0;
47
  private static final long serialVersionUID = 6108874887143696463L;
48
 
49
  /**
50
   * The constant zero as a BigDecimal with scale zero.
51
   * @since 1.5
52
   */
53
  public static final BigDecimal ZERO =
54
    new BigDecimal (BigInteger.ZERO, 0);
55
 
56
  /**
57
   * The constant one as a BigDecimal with scale zero.
58
   * @since 1.5
59
   */
60
  public static final BigDecimal ONE =
61
    new BigDecimal (BigInteger.ONE, 0);
62
 
63
  /**
64
   * The constant ten as a BigDecimal with scale zero.
65
   * @since 1.5
66
   */
67
  public static final BigDecimal TEN =
68
    new BigDecimal (BigInteger.TEN, 0);
69
 
70
  public static final int ROUND_UP = 0;
71
  public static final int ROUND_DOWN = 1;
72
  public static final int ROUND_CEILING = 2;
73
  public static final int ROUND_FLOOR = 3;
74
  public static final int ROUND_HALF_UP = 4;
75
  public static final int ROUND_HALF_DOWN = 5;
76
  public static final int ROUND_HALF_EVEN = 6;
77
  public static final int ROUND_UNNECESSARY = 7;
78
 
79
  /**
80
   * Constructs a new BigDecimal whose unscaled value is val and whose
81
   * scale is zero.
82
   * @param val the value of the new BigDecimal
83
   * @since 1.5
84
   */
85
  public BigDecimal (int val)
86
  {
87
    this.intVal = BigInteger.valueOf(val);
88
    this.scale = 0;
89
  }
90
 
91
  /**
92
   * Constructs a BigDecimal using the BigDecimal(int) constructor and then
93
   * rounds according to the MathContext.
94
   * @param val the value for the initial (unrounded) BigDecimal
95
   * @param mc the MathContext specifying the rounding
96
   * @throws ArithmeticException if the result is inexact but the rounding type
97
   * is RoundingMode.UNNECESSARY
98
   * @since 1.5
99
   */
100
  public BigDecimal (int val, MathContext mc)
101
  {
102
    this (val);
103
    if (mc.getPrecision() != 0)
104
      {
105
        BigDecimal result = this.round(mc);
106
        this.intVal = result.intVal;
107
        this.scale = result.scale;
108
        this.precision = result.precision;
109
      }
110
  }
111
 
112
  /**
113
   * Constructs a new BigDecimal whose unscaled value is val and whose
114
   * scale is zero.
115
   * @param val the value of the new BigDecimal
116
   */
117
  public BigDecimal (long val)
118
  {
119
    this.intVal = BigInteger.valueOf(val);
120
    this.scale = 0;
121
  }
122
 
123
  /**
124
   * Constructs a BigDecimal from the long in the same way as BigDecimal(long)
125
   * and then rounds according to the MathContext.
126
   * @param val the long from which we create the initial BigDecimal
127
   * @param mc the MathContext that specifies the rounding behaviour
128
   * @throws ArithmeticException if the result is inexact but the rounding type
129
   * is RoundingMode.UNNECESSARY
130
   * @since 1.5
131
   */
132
  public BigDecimal (long val, MathContext mc)
133
  {
134
    this(val);
135
    if (mc.getPrecision() != 0)
136
      {
137
        BigDecimal result = this.round(mc);
138
        this.intVal = result.intVal;
139
        this.scale = result.scale;
140
        this.precision = result.precision;
141
      }
142
  }
143
 
144
  /**
145
   * Constructs a BigDecimal whose value is given by num rounded according to
146
   * mc.  Since num is already a BigInteger, the rounding refers only to the
147
   * precision setting in mc, if mc.getPrecision() returns an int lower than
148
   * the number of digits in num, then rounding is necessary.
149
   * @param num the unscaledValue, before rounding
150
   * @param mc the MathContext that specifies the precision
151
   * @throws ArithmeticException if the result is inexact but the rounding type
152
   * is RoundingMode.UNNECESSARY
153
   * * @since 1.5
154
   */
155
  public BigDecimal (BigInteger num, MathContext mc)
156
  {
157
    this (num, 0);
158
    if (mc.getPrecision() != 0)
159
      {
160
        BigDecimal result = this.round(mc);
161
        this.intVal = result.intVal;
162
        this.scale = result.scale;
163
        this.precision = result.precision;
164
      }
165
  }
166
 
167
  /**
168
   * Constructs a BigDecimal from the String val according to the same
169
   * rules as the BigDecimal(String) constructor and then rounds
170
   * according to the MathContext mc.
171
   * @param val the String from which we construct the initial BigDecimal
172
   * @param mc the MathContext that specifies the rounding
173
   * @throws ArithmeticException if the result is inexact but the rounding type
174
   * is RoundingMode.UNNECESSARY
175
   * @since 1.5
176
   */
177
  public BigDecimal (String val, MathContext mc)
178
  {
179
    this (val);
180
    if (mc.getPrecision() != 0)
181
      {
182
        BigDecimal result = this.round(mc);
183
        this.intVal = result.intVal;
184
        this.scale = result.scale;
185
        this.precision = result.precision;
186
      }
187
  }
188
 
189
  /**
190
   * Constructs a BigDecimal whose unscaled value is num and whose
191
   * scale is zero.
192
   * @param num the value of the new BigDecimal
193
   */
194
  public BigDecimal (BigInteger num)
195
  {
196
    this (num, 0);
197
  }
198
 
199
  /**
200
   * Constructs a BigDecimal whose unscaled value is num and whose
201
   * scale is scale.
202
   * @param num
203
   * @param scale
204
   */
205
  public BigDecimal (BigInteger num, int scale)
206
  {
207
    this.intVal = num;
208
    this.scale = scale;
209
  }
210
 
211
  /**
212
   * Constructs a BigDecimal using the BigDecimal(BigInteger, int)
213
   * constructor and then rounds according to the MathContext.
214
   * @param num the unscaled value of the unrounded BigDecimal
215
   * @param scale the scale of the unrounded BigDecimal
216
   * @param mc the MathContext specifying the rounding
217
   * @throws ArithmeticException if the result is inexact but the rounding type
218
   * is RoundingMode.UNNECESSARY
219
   * @since 1.5
220
   */
221
  public BigDecimal (BigInteger num, int scale, MathContext mc)
222
  {
223
    this (num, scale);
224
    if (mc.getPrecision() != 0)
225
      {
226
        BigDecimal result = this.round(mc);
227
        this.intVal = result.intVal;
228
        this.scale = result.scale;
229
        this.precision = result.precision;
230
      }
231
  }
232
 
233
  /**
234
   * Constructs a BigDecimal in the same way as BigDecimal(double) and then
235
   * rounds according to the MathContext.
236
   * @param num the double from which the initial BigDecimal is created
237
   * @param mc the MathContext that specifies the rounding behaviour
238
   * @throws ArithmeticException if the result is inexact but the rounding type
239
   * is RoundingMode.UNNECESSARY
240
   * @since 1.5
241
   */
242
  public BigDecimal (double num, MathContext mc)
243
  {
244
    this (num);
245
    if (mc.getPrecision() != 0)
246
      {
247
        BigDecimal result = this.round(mc);
248
        this.intVal = result.intVal;
249
        this.scale = result.scale;
250
        this.precision = result.precision;
251
      }
252
  }
253
 
254
  public BigDecimal (double num) throws NumberFormatException
255
  {
256
    if (Double.isInfinite (num) || Double.isNaN (num))
257
      throw new NumberFormatException ("invalid argument: " + num);
258
    // Note we can't convert NUM to a String and then use the
259
    // String-based constructor.  The BigDecimal documentation makes
260
    // it clear that the two constructors work differently.
261
 
262
    final int mantissaBits = 52;
263
    final int exponentBits = 11;
264
    final long mantMask = (1L << mantissaBits) - 1;
265
    final long expMask = (1L << exponentBits) - 1;
266
 
267
    long bits = Double.doubleToLongBits (num);
268
    long mantissa = bits & mantMask;
269
    long exponent = (bits >>> mantissaBits) & expMask;
270
    boolean denormal = exponent == 0;
271
 
272
    // Correct the exponent for the bias.
273
    exponent -= denormal ? 1022 : 1023;
274
 
275
    // Now correct the exponent to account for the bits to the right
276
    // of the decimal.
277
    exponent -= mantissaBits;
278
    // Ordinary numbers have an implied leading `1' bit.
279
    if (! denormal)
280
      mantissa |= (1L << mantissaBits);
281
 
282
    // Shave off factors of 10.
283
    while (exponent < 0 && (mantissa & 1) == 0)
284
      {
285
        ++exponent;
286
        mantissa >>= 1;
287
      }
288
 
289
    intVal = BigInteger.valueOf (bits < 0 ? - mantissa : mantissa);
290
    if (exponent < 0)
291
      {
292
        // We have MANTISSA * 2 ^ (EXPONENT).
293
        // Since (1/2)^N == 5^N * 10^-N we can easily convert this
294
        // into a power of 10.
295
        scale = (int) (- exponent);
296
        BigInteger mult = BigInteger.valueOf (5).pow (scale);
297
        intVal = intVal.multiply (mult);
298
      }
299
    else
300
      {
301
        intVal = intVal.shiftLeft ((int) exponent);
302
        scale = 0;
303
      }
304
  }
305
 
306
  /**
307
   * Constructs a BigDecimal from the char subarray and rounding
308
   * according to the MathContext.
309
   * @param in the char array
310
   * @param offset the start of the subarray
311
   * @param len the length of the subarray
312
   * @param mc the MathContext for rounding
313
   * @throws NumberFormatException if the char subarray is not a valid
314
   * BigDecimal representation
315
   * @throws ArithmeticException if the result is inexact but the rounding
316
   * mode is RoundingMode.UNNECESSARY
317
   * @since 1.5
318
   */
319
  public BigDecimal(char[] in, int offset, int len, MathContext mc)
320
  {
321
    this(in, offset, len);
322
    // If mc has precision other than zero then we must round.
323
    if (mc.getPrecision() != 0)
324
      {
325
        BigDecimal temp = this.round(mc);
326
        this.intVal = temp.intVal;
327
        this.scale = temp.scale;
328
        this.precision = temp.precision;
329
      }
330
  }
331
 
332
  /**
333
   * Constructs a BigDecimal from the char array and rounding according
334
   * to the MathContext.
335
   * @param in the char array
336
   * @param mc the MathContext
337
   * @throws NumberFormatException if <code>in</code> is not a valid BigDecimal
338
   * representation
339
   * @throws ArithmeticException if the result is inexact but the rounding mode
340
   * is RoundingMode.UNNECESSARY
341
   * @since 1.5
342
   */
343
  public BigDecimal(char[] in, MathContext mc)
344
  {
345
    this(in, 0, in.length);
346
    // If mc has precision other than zero then we must round.
347
    if (mc.getPrecision() != 0)
348
      {
349
        BigDecimal temp = this.round(mc);
350
        this.intVal = temp.intVal;
351
        this.scale = temp.scale;
352
        this.precision = temp.precision;
353
      }
354
  }
355
 
356
  /**
357
   * Constructs a BigDecimal from the given char array, accepting the same
358
   * sequence of characters as the BigDecimal(String) constructor.
359
   * @param in the char array
360
   * @throws NumberFormatException if <code>in</code> is not a valid BigDecimal
361
   * representation
362
   * @since 1.5
363
   */
364
  public BigDecimal(char[] in)
365
  {
366
    this(in, 0, in.length);
367
  }
368
 
369
  /**
370
   * Constructs a BigDecimal from a char subarray, accepting the same sequence
371
   * of characters as the BigDecimal(String) constructor.
372
   * @param in the char array
373
   * @param offset the start of the subarray
374
   * @param len the length of the subarray
375
   * @throws NumberFormatException if <code>in</code> is not a valid
376
   * BigDecimal representation.
377
   * @since 1.5
378
   */
379
  public BigDecimal(char[] in, int offset, int len)
380
  {
381
    //  start is the index into the char array where the significand starts
382
    int start = offset;
383
    //  end is one greater than the index of the last character used
384
    int end = offset + len;
385
    //  point is the index into the char array where the exponent starts
386
    //  (or, if there is no exponent, this is equal to end)
387
    int point = offset;
388
    //  dot is the index into the char array where the decimal point is
389
    //  found, or -1 if there is no decimal point
390
    int dot = -1;
391
 
392
    //  The following examples show what these variables mean.  Note that
393
    //  point and dot don't yet have the correct values, they will be
394
    //  properly assigned in a loop later on in this method.
395
    //
396
    //  Example 1
397
    //
398
    //         +  1  0  2  .  4  6  9
399
    //  __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
400
    //
401
    //  offset = 2, len = 8, start = 3, dot = 6, point = end = 10
402
    //
403
    //  Example 2
404
    //
405
    //         +  2  3  4  .  6  1  3  E  -  1
406
    //  __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
407
    //
408
    //  offset = 2, len = 11, start = 3, dot = 6, point = 10, end = 13
409
    //
410
    //  Example 3
411
    //
412
    //         -  1  2  3  4  5  e  7
413
    //  __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
414
    //
415
    //  offset = 2, len = 8, start = 3, dot = -1, point = 8, end = 10
416
 
417
    //  Determine the sign of the number.
418
    boolean negative = false;
419
    if (in[offset] == '+')
420
      {
421
        ++start;
422
        ++point;
423
      }
424
    else if (in[offset] == '-')
425
      {
426
        ++start;
427
        ++point;
428
        negative = true;
429
      }
430
 
431
    //  Check each character looking for the decimal point and the
432
    //  start of the exponent.
433
    while (point < end)
434
      {
435
        char c = in[point];
436
        if (c == '.')
437
          {
438
            // If dot != -1 then we've seen more than one decimal point.
439
            if (dot != -1)
440
              throw new NumberFormatException("multiple `.'s in number");
441
            dot = point;
442
          }
443
        // Break when we reach the start of the exponent.
444
        else if (c == 'e' || c == 'E')
445
          break;
446
        // Throw an exception if the character was not a decimal or an
447
        // exponent and is not a digit.
448
        else if (!Character.isDigit(c))
449
          throw new NumberFormatException("unrecognized character at " + point
450
                                          + ": " + c);
451
        ++point;
452
      }
453
 
454
    // val is a StringBuilder from which we'll create a BigInteger
455
    // which will be the unscaled value for this BigDecimal
456
    CPStringBuilder val = new CPStringBuilder(point - start - 1);
457
    if (dot != -1)
458
      {
459
        // If there was a decimal we must combine the two parts that
460
        // contain only digits and we must set the scale properly.
461
        val.append(in, start, dot - start);
462
        val.append(in, dot + 1, point - dot - 1);
463
        scale = point - 1 - dot;
464
      }
465
    else
466
      {
467
        // If there was no decimal then the unscaled value is just the number
468
        // formed from all the digits and the scale is zero.
469
        val.append(in, start, point - start);
470
        scale = 0;
471
      }
472
    if (val.length() == 0)
473
      throw new NumberFormatException("no digits seen");
474
 
475
    // Prepend a negative sign if necessary.
476
    if (negative)
477
      val.insert(0, '-');
478
    intVal = new BigInteger(val.toString());
479
 
480
    // Now parse exponent.
481
    // If point < end that means we broke out of the previous loop when we
482
    // saw an 'e' or an 'E'.
483
    if (point < end)
484
      {
485
        point++;
486
        // Ignore a '+' sign.
487
        if (in[point] == '+')
488
          point++;
489
 
490
        // Throw an exception if there were no digits found after the 'e'
491
        // or 'E'.
492
        if (point >= end)
493
          throw new NumberFormatException("no exponent following e or E");
494
 
495
        try
496
          {
497
            // Adjust the scale according to the exponent.
498
            // Remember that the value of a BigDecimal is
499
            // unscaledValue x Math.pow(10, -scale)
500
            scale -= Integer.parseInt(new String(in, point, end - point));
501
          }
502
        catch (NumberFormatException ex)
503
          {
504
            throw new NumberFormatException("malformed exponent");
505
          }
506
      }
507
  }
508
 
509
  public BigDecimal (String num) throws NumberFormatException
510
  {
511
    int len = num.length();
512
    int start = 0, point = 0;
513
    int dot = -1;
514
    boolean negative = false;
515
    if (num.charAt(0) == '+')
516
      {
517
        ++start;
518
        ++point;
519
      }
520
    else if (num.charAt(0) == '-')
521
      {
522
        ++start;
523
        ++point;
524
        negative = true;
525
      }
526
 
527
    while (point < len)
528
      {
529
        char c = num.charAt (point);
530
        if (c == '.')
531
          {
532
            if (dot >= 0)
533
              throw new NumberFormatException ("multiple `.'s in number");
534
            dot = point;
535
          }
536
        else if (c == 'e' || c == 'E')
537
          break;
538
        else if (Character.digit (c, 10) < 0)
539
          throw new NumberFormatException ("unrecognized character: " + c);
540
        ++point;
541
      }
542
 
543
    String val;
544
    if (dot >= 0)
545
      {
546
        val = num.substring (start, dot) + num.substring (dot + 1, point);
547
        scale = point - 1 - dot;
548
      }
549
    else
550
      {
551
        val = num.substring (start, point);
552
        scale = 0;
553
      }
554
    if (val.length () == 0)
555
      throw new NumberFormatException ("no digits seen");
556
 
557
    if (negative)
558
      val = "-" + val;
559
    intVal = new BigInteger (val);
560
 
561
    // Now parse exponent.
562
    if (point < len)
563
      {
564
        point++;
565
        if (num.charAt(point) == '+')
566
          point++;
567
 
568
        if (point >= len )
569
          throw new NumberFormatException ("no exponent following e or E");
570
 
571
        try
572
          {
573
        scale -= Integer.parseInt (num.substring (point));
574
          }
575
        catch (NumberFormatException ex)
576
          {
577
            throw new NumberFormatException ("malformed exponent");
578
          }
579
      }
580
  }
581
 
582
  public static BigDecimal valueOf (long val)
583
  {
584
    return valueOf (val, 0);
585
  }
586
 
587
  public static BigDecimal valueOf (long val, int scale)
588
    throws NumberFormatException
589
  {
590
    if ((scale == 0) && ((int)val == val))
591
      switch ((int) val)
592
        {
593
        case 0:
594
          return ZERO;
595
        case 1:
596
          return ONE;
597
        }
598
 
599
    return new BigDecimal (BigInteger.valueOf (val), scale);
600
  }
601
 
602
  public BigDecimal add (BigDecimal val)
603
  {
604
    // For addition, need to line up decimals.  Note that the movePointRight
605
    // method cannot be used for this as it might return a BigDecimal with
606
    // scale == 0 instead of the scale we need.
607
    BigInteger op1 = intVal;
608
    BigInteger op2 = val.intVal;
609
    if (scale < val.scale)
610
      op1 = op1.multiply (BigInteger.TEN.pow (val.scale - scale));
611
    else if (scale > val.scale)
612
      op2 = op2.multiply (BigInteger.TEN.pow (scale - val.scale));
613
 
614
    return new BigDecimal (op1.add (op2), Math.max (scale, val.scale));
615
  }
616
 
617
  /**
618
   * Returns a BigDecimal whose value is found first by calling the
619
   * method add(val) and then by rounding according to the MathContext mc.
620
   * @param val the augend
621
   * @param mc the MathContext for rounding
622
   * @throws ArithmeticException if the value is inexact but the rounding is
623
   * RoundingMode.UNNECESSARY
624
   * @return <code>this</code> + <code>val</code>, rounded if need be
625
   * @since 1.5
626
   */
627
  public BigDecimal add (BigDecimal val, MathContext mc)
628
  {
629
    return add(val).round(mc);
630
  }
631
 
632
  public BigDecimal subtract (BigDecimal val)
633
  {
634
    return this.add(val.negate());
635
  }
636
 
637
  /**
638
   * Returns a BigDecimal whose value is found first by calling the
639
   * method subtract(val) and then by rounding according to the MathContext mc.
640
   * @param val the subtrahend
641
   * @param mc the MathContext for rounding
642
   * @throws ArithmeticException if the value is inexact but the rounding is
643
   * RoundingMode.UNNECESSARY
644
   * @return <code>this</code> - <code>val</code>, rounded if need be
645
   * @since 1.5
646
   */
647
  public BigDecimal subtract (BigDecimal val, MathContext mc)
648
  {
649
    return subtract(val).round(mc);
650
  }
651
 
652
  public BigDecimal multiply (BigDecimal val)
653
  {
654
    return new BigDecimal (intVal.multiply (val.intVal), scale + val.scale);
655
  }
656
 
657
  /**
658
   * Returns a BigDecimal whose value is (this x val) before it is rounded
659
   * according to the MathContext mc.
660
   * @param val the multiplicand
661
   * @param mc the MathContext for rounding
662
   * @return a new BigDecimal with value approximately (this x val)
663
   * @throws ArithmeticException if the value is inexact but the rounding mode
664
   * is RoundingMode.UNNECESSARY
665
   * @since 1.5
666
   */
667
  public BigDecimal multiply (BigDecimal val, MathContext mc)
668
  {
669
    return multiply(val).round(mc);
670
  }
671
 
672
  public BigDecimal divide (BigDecimal val, int roundingMode)
673
    throws ArithmeticException, IllegalArgumentException
674
  {
675
    return divide (val, scale, roundingMode);
676
  }
677
 
678
  /**
679
   * Returns a BigDecimal whose value is (this / val), with the specified scale
680
   * and rounding according to the RoundingMode
681
   * @param val the divisor
682
   * @param scale the scale of the BigDecimal returned
683
   * @param roundingMode the rounding mode to use
684
   * @return a BigDecimal whose value is approximately (this / val)
685
   * @throws ArithmeticException if divisor is zero or the rounding mode is
686
   * UNNECESSARY but the specified scale cannot represent the value exactly
687
   * @since 1.5
688
   */
689
  public BigDecimal divide(BigDecimal val,
690
                           int scale, RoundingMode roundingMode)
691
  {
692
    return divide (val, scale, roundingMode.ordinal());
693
  }
694
 
695
  /**
696
   * Returns a BigDecimal whose value is (this / val) rounded according to the
697
   * RoundingMode
698
   * @param val the divisor
699
   * @param roundingMode the rounding mode to use
700
   * @return a BigDecimal whose value is approximately (this / val)
701
   * @throws ArithmeticException if divisor is zero or the rounding mode is
702
   * UNNECESSARY but the specified scale cannot represent the value exactly
703
   */
704
  public BigDecimal divide (BigDecimal val, RoundingMode roundingMode)
705
  {
706
    return divide (val, scale, roundingMode.ordinal());
707
  }
708
 
709
  public BigDecimal divide(BigDecimal val, int newScale, int roundingMode)
710
    throws ArithmeticException, IllegalArgumentException
711
  {
712
    if (roundingMode < 0 || roundingMode > 7)
713
      throw
714
        new IllegalArgumentException("illegal rounding mode: " + roundingMode);
715
 
716
    if (intVal.signum () == 0)  // handle special case of 0.0/0.0
717
      return newScale == 0 ? ZERO : new BigDecimal (ZERO.intVal, newScale);
718
 
719
    // Ensure that pow gets a non-negative value.
720
    BigInteger valIntVal = val.intVal;
721
    int power = newScale - (scale - val.scale);
722
    if (power < 0)
723
      {
724
        // Effectively increase the scale of val to avoid an
725
        // ArithmeticException for a negative power.
726
        valIntVal = valIntVal.multiply (BigInteger.TEN.pow (-power));
727
        power = 0;
728
      }
729
 
730
    BigInteger dividend = intVal.multiply (BigInteger.TEN.pow (power));
731
 
732
    BigInteger parts[] = dividend.divideAndRemainder (valIntVal);
733
 
734
    BigInteger unrounded = parts[0];
735
    if (parts[1].signum () == 0) // no remainder, no rounding necessary
736
      return new BigDecimal (unrounded, newScale);
737
 
738
    if (roundingMode == ROUND_UNNECESSARY)
739
      throw new ArithmeticException ("Rounding necessary");
740
 
741
    int sign = intVal.signum () * valIntVal.signum ();
742
 
743
    if (roundingMode == ROUND_CEILING)
744
      roundingMode = (sign > 0) ? ROUND_UP : ROUND_DOWN;
745
    else if (roundingMode == ROUND_FLOOR)
746
      roundingMode = (sign < 0) ? ROUND_UP : ROUND_DOWN;
747
    else
748
      {
749
        // half is -1 if remainder*2 < positive intValue (*power), 0 if equal,
750
        // 1 if >. This implies that the remainder to round is less than,
751
        // equal to, or greater than half way to the next digit.
752
        BigInteger posRemainder
753
          = parts[1].signum () < 0 ? parts[1].negate() : parts[1];
754
        valIntVal = valIntVal.signum () < 0 ? valIntVal.negate () : valIntVal;
755
        int half = posRemainder.shiftLeft(1).compareTo(valIntVal);
756
 
757
        switch(roundingMode)
758
          {
759
          case ROUND_HALF_UP:
760
            roundingMode = (half < 0) ? ROUND_DOWN : ROUND_UP;
761
            break;
762
          case ROUND_HALF_DOWN:
763
            roundingMode = (half > 0) ? ROUND_UP : ROUND_DOWN;
764
            break;
765
          case ROUND_HALF_EVEN:
766
            if (half < 0)
767
              roundingMode = ROUND_DOWN;
768
            else if (half > 0)
769
              roundingMode = ROUND_UP;
770
            else if (unrounded.testBit(0)) // odd, then ROUND_HALF_UP
771
              roundingMode = ROUND_UP;
772
            else                           // even, ROUND_HALF_DOWN
773
              roundingMode = ROUND_DOWN;
774
            break;
775
          }
776
      }
777
 
778
    if (roundingMode == ROUND_UP)
779
      unrounded = unrounded.add (BigInteger.valueOf (sign > 0 ? 1 : -1));
780
 
781
    // roundingMode == ROUND_DOWN
782
    return new BigDecimal (unrounded, newScale);
783
  }
784
 
785
  /**
786
   * Performs division, if the resulting quotient requires rounding
787
   * (has a nonterminating decimal expansion),
788
   * an ArithmeticException is thrown.
789
   * #see divide(BigDecimal, int, int)
790
   * @since 1.5
791
   */
792
  public BigDecimal divide(BigDecimal divisor)
793
    throws ArithmeticException, IllegalArgumentException
794
  {
795
    return divide(divisor, scale, ROUND_UNNECESSARY);
796
  }
797
 
798
  /**
799
   * Returns a BigDecimal whose value is the remainder in the quotient
800
   * this / val.  This is obtained by
801
   * subtract(divideToIntegralValue(val).multiply(val)).
802
   * @param val the divisor
803
   * @return a BigDecimal whose value is the remainder
804
   * @throws ArithmeticException if val == 0
805
   * @since 1.5
806
   */
807
  public BigDecimal remainder(BigDecimal val)
808
  {
809
    return subtract(divideToIntegralValue(val).multiply(val));
810
  }
811
 
812
  /**
813
   * Returns a BigDecimal array, the first element of which is the integer part
814
   * of this / val, and the second element of which is the remainder of
815
   * that quotient.
816
   * @param val the divisor
817
   * @return the above described BigDecimal array
818
   * @throws ArithmeticException if val == 0
819
   * @since 1.5
820
   */
821
  public BigDecimal[] divideAndRemainder(BigDecimal val)
822
  {
823
    BigDecimal[] result = new BigDecimal[2];
824
    result[0] = divideToIntegralValue(val);
825
    result[1] = subtract(result[0].multiply(val));
826
    return result;
827
  }
828
 
829
  /**
830
   * Returns a BigDecimal whose value is the integer part of the quotient
831
   * this / val.  The preferred scale is this.scale - val.scale.
832
   * @param val the divisor
833
   * @return a BigDecimal whose value is the integer part of this / val.
834
   * @throws ArithmeticException if val == 0
835
   * @since 1.5
836
   */
837
  public BigDecimal divideToIntegralValue(BigDecimal val)
838
  {
839
    return divide(val, ROUND_DOWN).floor().setScale(scale - val.scale, ROUND_DOWN);
840
  }
841
 
842
  /**
843
   * Mutates this BigDecimal into one with no fractional part, whose value is
844
   * equal to the largest integer that is <= to this BigDecimal.  Note that
845
   * since this method is private it is okay to mutate this BigDecimal.
846
   * @return the BigDecimal obtained through the floor operation on this
847
   * BigDecimal.
848
   */
849
  private BigDecimal floor()
850
  {
851
    if (scale <= 0)
852
      return this;
853
    String intValStr = intVal.toString();
854
    intValStr = intValStr.substring(0, intValStr.length() - scale);
855
    intVal = new BigInteger(intValStr).multiply(BigInteger.TEN.pow(scale));
856
    return this;
857
  }
858
 
859
  public int compareTo (BigDecimal val)
860
  {
861
    if (scale == val.scale)
862
      return intVal.compareTo (val.intVal);
863
 
864
    BigInteger thisParts[] =
865
      intVal.divideAndRemainder (BigInteger.TEN.pow (scale));
866
    BigInteger valParts[] =
867
      val.intVal.divideAndRemainder (BigInteger.TEN.pow (val.scale));
868
 
869
    int compare;
870
    if ((compare = thisParts[0].compareTo (valParts[0])) != 0)
871
      return compare;
872
 
873
    // quotients are the same, so compare remainders
874
 
875
    // Add some trailing zeros to the remainder with the smallest scale
876
    if (scale < val.scale)
877
      thisParts[1] = thisParts[1].multiply
878
                        (BigInteger.valueOf (10).pow (val.scale - scale));
879
    else if (scale > val.scale)
880
      valParts[1] = valParts[1].multiply
881
                        (BigInteger.valueOf (10).pow (scale - val.scale));
882
 
883
    // and compare them
884
    return thisParts[1].compareTo (valParts[1]);
885
  }
886
 
887
  public boolean equals (Object o)
888
  {
889
    return (o instanceof BigDecimal
890
            && scale == ((BigDecimal) o).scale
891
            && compareTo ((BigDecimal) o) == 0);
892
  }
893
 
894
  public int hashCode()
895
  {
896
    return intValue() ^ scale;
897
  }
898
 
899
  public BigDecimal max (BigDecimal val)
900
  {
901
    switch (compareTo (val))
902
      {
903
      case 1:
904
        return this;
905
      default:
906
        return val;
907
      }
908
  }
909
 
910
  public BigDecimal min (BigDecimal val)
911
  {
912
    switch (compareTo (val))
913
      {
914
      case -1:
915
        return this;
916
      default:
917
        return val;
918
      }
919
  }
920
 
921
  public BigDecimal movePointLeft (int n)
922
  {
923
    return (n < 0) ? movePointRight (-n) : new BigDecimal (intVal, scale + n);
924
  }
925
 
926
  public BigDecimal movePointRight (int n)
927
  {
928
    if (n < 0)
929
      return movePointLeft (-n);
930
 
931
    if (scale >= n)
932
      return new BigDecimal (intVal, scale - n);
933
 
934
    return new BigDecimal (intVal.multiply
935
                           (BigInteger.TEN.pow (n - scale)), 0);
936
  }
937
 
938
  public int signum ()
939
  {
940
    return intVal.signum ();
941
  }
942
 
943
  public int scale ()
944
  {
945
    return scale;
946
  }
947
 
948
  public BigInteger unscaledValue()
949
  {
950
    return intVal;
951
  }
952
 
953
  public BigDecimal abs ()
954
  {
955
    return new BigDecimal (intVal.abs (), scale);
956
  }
957
 
958
  public BigDecimal negate ()
959
  {
960
    return new BigDecimal (intVal.negate (), scale);
961
  }
962
 
963
  /**
964
   * Returns a BigDecimal whose value is found first by negating this via
965
   * the negate() method, then by rounding according to the MathContext mc.
966
   * @param mc the MathContext for rounding
967
   * @return a BigDecimal whose value is approximately (-this)
968
   * @throws ArithmeticException if the value is inexact but the rounding mode
969
   * is RoundingMode.UNNECESSARY
970
   * @since 1.5
971
   */
972
  public BigDecimal negate(MathContext mc)
973
  {
974
    BigDecimal result = negate();
975
    if (mc.getPrecision() != 0)
976
      result = result.round(mc);
977
    return result;
978
  }
979
 
980
  /**
981
   * Returns this BigDecimal.  This is included for symmetry with the
982
   * method negate().
983
   * @return this
984
   * @since 1.5
985
   */
986
  public BigDecimal plus()
987
  {
988
    return this;
989
  }
990
 
991
  /**
992
   * Returns a BigDecimal whose value is found by rounding <code>this</code>
993
   * according to the MathContext.  This is the same as round(MathContext).
994
   * @param mc the MathContext for rounding
995
   * @return a BigDecimal whose value is <code>this</code> before being rounded
996
   * @throws ArithmeticException if the value is inexact but the rounding mode
997
   * is RoundingMode.UNNECESSARY
998
   * @since 1.5
999
   */
1000
  public BigDecimal plus(MathContext mc)
1001
  {
1002
    return round(mc);
1003
  }
1004
 
1005
  /**
1006
   * Returns a BigDecimal which is this BigDecimal rounded according to the
1007
   * MathContext rounding settings.
1008
   * @param mc the MathContext that tells us how to round
1009
   * @return the rounded BigDecimal
1010
   */
1011
  public BigDecimal round(MathContext mc)
1012
  {
1013
    int mcPrecision = mc.getPrecision();
1014
    int numToChop = precision() - mcPrecision;
1015
    // If mc specifies not to chop any digits or if we've already chopped
1016
    // enough digits (say by using a MathContext in the constructor for this
1017
    // BigDecimal) then just return this.
1018
    if (mcPrecision == 0 || numToChop <= 0)
1019
      return this;
1020
 
1021
    // Make a new BigDecimal which is the correct power of 10 to chop off
1022
    // the required number of digits and then call divide.
1023
    BigDecimal div = new BigDecimal(BigInteger.TEN.pow(numToChop));
1024
    BigDecimal rounded = divide(div, scale, mc.getRoundingMode().ordinal());
1025
    rounded.scale -= numToChop;
1026
    rounded.precision = mcPrecision;
1027
    return rounded;
1028
  }
1029
 
1030
  /**
1031
   * Returns the precision of this BigDecimal (the number of digits in the
1032
   * unscaled value).  The precision of a zero value is 1.
1033
   * @return the number of digits in the unscaled value, or 1 if the value
1034
   * is zero.
1035
   */
1036
  public int precision()
1037
  {
1038
    if (precision == 0)
1039
      {
1040
        String s = intVal.toString();
1041
        precision = s.length() - (( s.charAt(0) == '-' ) ? 1 : 0);
1042
      }
1043
    return precision;
1044
  }
1045
 
1046
  /**
1047
   * Returns the String representation of this BigDecimal, using scientific
1048
   * notation if necessary.  The following steps are taken to generate
1049
   * the result:
1050
   *
1051
   * 1. the BigInteger unscaledValue's toString method is called and if
1052
   * <code>scale == 0<code> is returned.
1053
   * 2. an <code>int adjExp</code> is created which is equal to the negation
1054
   * of <code>scale</code> plus the number of digits in the unscaled value,
1055
   * minus one.
1056
   * 3. if <code>scale >= 0 && adjExp >= -6</code> then we represent this
1057
   * BigDecimal without scientific notation.  A decimal is added if the
1058
   * scale is positive and zeros are prepended as necessary.
1059
   * 4. if scale is negative or adjExp is less than -6 we use scientific
1060
   * notation.  If the unscaled value has more than one digit, a decimal
1061
   * as inserted after the first digit, the character 'E' is appended
1062
   * and adjExp is appended.
1063
   */
1064
  public String toString()
1065
  {
1066
    // bigStr is the String representation of the unscaled value.  If
1067
    // scale is zero we simply return this.
1068
    String bigStr = intVal.toString();
1069
    if (scale == 0)
1070
      return bigStr;
1071
 
1072
    boolean negative = (bigStr.charAt(0) == '-');
1073
    int point = bigStr.length() - scale - (negative ? 1 : 0);
1074
 
1075
    CPStringBuilder val = new CPStringBuilder();
1076
 
1077
    if (scale >= 0 && (point - 1) >= -6)
1078
      {
1079
        // Convert to character form without scientific notation.
1080
        if (point <= 0)
1081
          {
1082
            // Zeros need to be prepended to the StringBuilder.
1083
            if (negative)
1084
              val.append('-');
1085
            // Prepend a '0' and a '.' and then as many more '0's as necessary.
1086
            val.append('0').append('.');
1087
            while (point < 0)
1088
              {
1089
                val.append('0');
1090
                point++;
1091
              }
1092
            // Append the unscaled value.
1093
            val.append(bigStr.substring(negative ? 1 : 0));
1094
          }
1095
        else
1096
          {
1097
            // No zeros need to be prepended so the String is simply the
1098
            // unscaled value with the decimal point inserted.
1099
            val.append(bigStr);
1100
            val.insert(point + (negative ? 1 : 0), '.');
1101
          }
1102
      }
1103
    else
1104
      {
1105
        // We must use scientific notation to represent this BigDecimal.
1106
        val.append(bigStr);
1107
        // If there is more than one digit in the unscaled value we put a
1108
        // decimal after the first digit.
1109
        if (bigStr.length() > 1)
1110
          val.insert( ( negative ? 2 : 1 ), '.');
1111
        // And then append 'E' and the exponent = (point - 1).
1112
        val.append('E');
1113
        if (point - 1 >= 0)
1114
          val.append('+');
1115
        val.append( point - 1 );
1116
      }
1117
    return val.toString();
1118
  }
1119
 
1120
  /**
1121
   * Returns the String representation of this BigDecimal, using engineering
1122
   * notation if necessary.  This is similar to toString() but when exponents
1123
   * are used the exponent is made to be a multiple of 3 such that the integer
1124
   * part is between 1 and 999.
1125
   *
1126
   * @return a String representation of this BigDecimal in engineering notation
1127
   * @since 1.5
1128
   */
1129
  public String toEngineeringString()
1130
  {
1131
    // bigStr is the String representation of the unscaled value.  If
1132
    // scale is zero we simply return this.
1133
    String bigStr = intVal.toString();
1134
    if (scale == 0)
1135
      return bigStr;
1136
 
1137
    boolean negative = (bigStr.charAt(0) == '-');
1138
    int point = bigStr.length() - scale - (negative ? 1 : 0);
1139
 
1140
    // This is the adjusted exponent described above.
1141
    int adjExp = point - 1;
1142
    CPStringBuilder val = new CPStringBuilder();
1143
 
1144
    if (scale >= 0 && adjExp >= -6)
1145
      {
1146
        // Convert to character form without scientific notation.
1147
        if (point <= 0)
1148
          {
1149
            // Zeros need to be prepended to the StringBuilder.
1150
            if (negative)
1151
              val.append('-');
1152
            // Prepend a '0' and a '.' and then as many more '0's as necessary.
1153
            val.append('0').append('.');
1154
            while (point < 0)
1155
              {
1156
                val.append('0');
1157
                point++;
1158
              }
1159
            // Append the unscaled value.
1160
            val.append(bigStr.substring(negative ? 1 : 0));
1161
          }
1162
        else
1163
          {
1164
            // No zeros need to be prepended so the String is simply the
1165
            // unscaled value with the decimal point inserted.
1166
            val.append(bigStr);
1167
            val.insert(point + (negative ? 1 : 0), '.');
1168
          }
1169
      }
1170
    else
1171
      {
1172
        // We must use scientific notation to represent this BigDecimal.
1173
        // The exponent must be a multiple of 3 and the integer part
1174
        // must be between 1 and 999.
1175
        val.append(bigStr);
1176
        int zeros = adjExp % 3;
1177
        int dot = 1;
1178
        if (adjExp > 0)
1179
          {
1180
            // If the exponent is positive we just move the decimal to the
1181
            // right and decrease the exponent until it is a multiple of 3.
1182
            dot += zeros;
1183
            adjExp -= zeros;
1184
          }
1185
        else
1186
          {
1187
            // If the exponent is negative then we move the dot to the right
1188
            // and decrease the exponent (increase its magnitude) until
1189
            // it is a multiple of 3.  Note that this is not adjExp -= zeros
1190
            // because the mod operator doesn't give us the distance to the
1191
            // correct multiple of 3.  (-5 mod 3) is -2 but the distance from
1192
            // -5 to the correct multiple of 3 (-6) is 1, not 2.
1193
            if (zeros == -2)
1194
              {
1195
                dot += 1;
1196
                adjExp -= 1;
1197
              }
1198
            else if (zeros == -1)
1199
              {
1200
                dot += 2;
1201
                adjExp -= 2;
1202
              }
1203
          }
1204
 
1205
        // Either we have to append zeros because, for example, 1.1E+5 should
1206
        // be 110E+3, or we just have to put the decimal in the right place.
1207
        if (dot > val.length())
1208
          {
1209
            while (dot > val.length())
1210
              val.append('0');
1211
          }
1212
        else if (bigStr.length() > dot)
1213
          val.insert(dot + (negative ? 1 : 0), '.');
1214
 
1215
        // And then append 'E' and the exponent (adjExp).
1216
        val.append('E');
1217
        if (adjExp >= 0)
1218
          val.append('+');
1219
        val.append(adjExp);
1220
      }
1221
    return val.toString();
1222
  }
1223
 
1224
  /**
1225
   * Returns a String representation of this BigDecimal without using
1226
   * scientific notation.  This is how toString() worked for releases 1.4
1227
   * and previous.  Zeros may be added to the end of the String.  For
1228
   * example, an unscaled value of 1234 and a scale of -3 would result in
1229
   * the String 1234000, but the toString() method would return
1230
   * 1.234E+6.
1231
   * @return a String representation of this BigDecimal
1232
   * @since 1.5
1233
   */
1234
  public String toPlainString()
1235
  {
1236
    // If the scale is zero we simply return the String representation of the
1237
    // unscaled value.
1238
    String bigStr = intVal.toString();
1239
    if (scale == 0)
1240
      return bigStr;
1241
 
1242
    // Remember if we have to put a negative sign at the start.
1243
    boolean negative = (bigStr.charAt(0) == '-');
1244
 
1245
    int point = bigStr.length() - scale - (negative ? 1 : 0);
1246
 
1247
    CPStringBuilder sb = new CPStringBuilder(bigStr.length() + 2
1248
                                             + (point <= 0 ? (-point + 1) : 0));
1249
    if (point <= 0)
1250
      {
1251
        // We have to prepend zeros and a decimal point.
1252
        if (negative)
1253
          sb.append('-');
1254
        sb.append('0').append('.');
1255
        while (point < 0)
1256
          {
1257
            sb.append('0');
1258
            point++;
1259
          }
1260
        sb.append(bigStr.substring(negative ? 1 : 0));
1261
      }
1262
    else if (point < bigStr.length())
1263
      {
1264
        // No zeros need to be prepended or appended, just put the decimal
1265
        // in the right place.
1266
        sb.append(bigStr);
1267
        sb.insert(point + (negative ? 1 : 0), '.');
1268
      }
1269
    else
1270
      {
1271
        // We must append zeros instead of using scientific notation.
1272
        sb.append(bigStr);
1273
        for (int i = bigStr.length(); i < point; i++)
1274
          sb.append('0');
1275
      }
1276
    return sb.toString();
1277
  }
1278
 
1279
  /**
1280
   * Converts this BigDecimal to a BigInteger.  Any fractional part will
1281
   * be discarded.
1282
   * @return a BigDecimal whose value is equal to floor[this]
1283
   */
1284
  public BigInteger toBigInteger ()
1285
  {
1286
    // If scale > 0 then we must divide, if scale > 0 then we must multiply,
1287
    // and if scale is zero then we just return intVal;
1288
    if (scale > 0)
1289
      return intVal.divide (BigInteger.TEN.pow (scale));
1290
    else if (scale < 0)
1291
      return intVal.multiply(BigInteger.TEN.pow(-scale));
1292
    return intVal;
1293
  }
1294
 
1295
  /**
1296
   * Converts this BigDecimal into a BigInteger, throwing an
1297
   * ArithmeticException if the conversion is not exact.
1298
   * @return a BigInteger whose value is equal to the value of this BigDecimal
1299
   * @since 1.5
1300
   */
1301
  public BigInteger toBigIntegerExact()
1302
  {
1303
    if (scale > 0)
1304
      {
1305
        // If we have to divide, we must check if the result is exact.
1306
        BigInteger[] result =
1307
          intVal.divideAndRemainder(BigInteger.TEN.pow(scale));
1308
        if (result[1].equals(BigInteger.ZERO))
1309
          return result[0];
1310
        throw new ArithmeticException("No exact BigInteger representation");
1311
      }
1312
    else if (scale < 0)
1313
      // If we're multiplying instead, then we needn't check for exactness.
1314
      return intVal.multiply(BigInteger.TEN.pow(-scale));
1315
    // If the scale is zero we can simply return intVal.
1316
    return intVal;
1317
  }
1318
 
1319
  public int intValue ()
1320
  {
1321
    return toBigInteger ().intValue ();
1322
  }
1323
 
1324
  /**
1325
   * Returns a BigDecimal which is numerically equal to this BigDecimal but
1326
   * with no trailing zeros in the representation.  For example, if this
1327
   * BigDecimal has [unscaledValue, scale] = [6313000, 4] this method returns
1328
   * a BigDecimal with [unscaledValue, scale] = [6313, 1].  As another
1329
   * example, [12400, -2] would become [124, -4].
1330
   * @return a numerically equal BigDecimal with no trailing zeros
1331
   */
1332
  public BigDecimal stripTrailingZeros()
1333
  {
1334
    String intValStr = intVal.toString();
1335
    int newScale = scale;
1336
    int pointer = intValStr.length() - 1;
1337
    // This loop adjusts pointer which will be used to give us the substring
1338
    // of intValStr to use in our new BigDecimal, and also accordingly
1339
    // adjusts the scale of our new BigDecimal.
1340
    while (intValStr.charAt(pointer) == '0')
1341
      {
1342
        pointer --;
1343
        newScale --;
1344
      }
1345
    // Create a new BigDecimal with the appropriate substring and then
1346
    // set its scale.
1347
    BigDecimal result = new BigDecimal(intValStr.substring(0, pointer + 1));
1348
    result.scale = newScale;
1349
    return result;
1350
  }
1351
 
1352
  public long longValue ()
1353
  {
1354
    return toBigInteger().longValue();
1355
  }
1356
 
1357
  public float floatValue()
1358
  {
1359
    return Float.valueOf(toString()).floatValue();
1360
  }
1361
 
1362
  public double doubleValue()
1363
  {
1364
    return Double.valueOf(toString()).doubleValue();
1365
  }
1366
 
1367
  public BigDecimal setScale (int scale) throws ArithmeticException
1368
  {
1369
    return setScale (scale, ROUND_UNNECESSARY);
1370
  }
1371
 
1372
  public BigDecimal setScale (int scale, int roundingMode)
1373
    throws ArithmeticException, IllegalArgumentException
1374
  {
1375
    // NOTE: The 1.5 JRE doesn't throw this, ones prior to it do and
1376
    // the spec says it should. Nevertheless, if 1.6 doesn't fix this
1377
    // we should consider removing it.
1378
    if( scale < 0 ) throw new ArithmeticException("Scale parameter < 0.");
1379
    return divide (ONE, scale, roundingMode);
1380
  }
1381
 
1382
  /**
1383
   * Returns a BigDecimal whose value is the same as this BigDecimal but whose
1384
   * representation has a scale of <code>newScale</code>.  If the scale is
1385
   * reduced then rounding may occur, according to the RoundingMode.
1386
   * @param newScale
1387
   * @param roundingMode
1388
   * @return a BigDecimal whose scale is as given, whose value is
1389
   * <code>this</code> with possible rounding
1390
   * @throws ArithmeticException if the rounding mode is UNNECESSARY but
1391
   * rounding is required
1392
   * @since 1.5
1393
   */
1394
  public BigDecimal setScale(int newScale, RoundingMode roundingMode)
1395
  {
1396
    return setScale(newScale, roundingMode.ordinal());
1397
  }
1398
 
1399
  /**
1400
   * Returns a new BigDecimal constructed from the BigDecimal(String)
1401
   * constructor using the Double.toString(double) method to obtain
1402
   * the String.
1403
   * @param val the double value used in Double.toString(double)
1404
   * @return a BigDecimal representation of val
1405
   * @throws NumberFormatException if val is NaN or infinite
1406
   * @since 1.5
1407
   */
1408
  public static BigDecimal valueOf(double val)
1409
  {
1410
    if (Double.isInfinite(val) || Double.isNaN(val))
1411
      throw new NumberFormatException("argument cannot be NaN or infinite.");
1412
    return new BigDecimal(Double.toString(val));
1413
  }
1414
 
1415
  /**
1416
   * Returns a BigDecimal whose numerical value is the numerical value
1417
   * of this BigDecimal multiplied by 10 to the power of <code>n</code>.
1418
   * @param n the power of ten
1419
   * @return the new BigDecimal
1420
   * @since 1.5
1421
   */
1422
  public BigDecimal scaleByPowerOfTen(int n)
1423
  {
1424
    BigDecimal result = new BigDecimal(intVal, scale - n);
1425
    result.precision = precision;
1426
    return result;
1427
  }
1428
 
1429
  /**
1430
   * Returns a BigDecimal whose value is <code>this</code> to the power of
1431
   * <code>n</code>.
1432
   * @param n the power
1433
   * @return the new BigDecimal
1434
   * @since 1.5
1435
   */
1436
  public BigDecimal pow(int n)
1437
  {
1438
    if (n < 0 || n > 999999999)
1439
      throw new ArithmeticException("n must be between 0 and 999999999");
1440
    BigDecimal result = new BigDecimal(intVal.pow(n), scale * n);
1441
    return result;
1442
  }
1443
 
1444
  /**
1445
   * Returns a BigDecimal whose value is determined by first calling pow(n)
1446
   * and then by rounding according to the MathContext mc.
1447
   * @param n the power
1448
   * @param mc the MathContext
1449
   * @return the new BigDecimal
1450
   * @throws ArithmeticException if n < 0 or n > 999999999 or if the result is
1451
   * inexact but the rounding is RoundingMode.UNNECESSARY
1452
   * @since 1.5
1453
   */
1454
  public BigDecimal pow(int n, MathContext mc)
1455
  {
1456
    // FIXME: The specs claim to use the X3.274-1996 algorithm.  We
1457
    // currently do not.
1458
    return pow(n).round(mc);
1459
  }
1460
 
1461
  /**
1462
   * Returns a BigDecimal whose value is the absolute value of this BigDecimal
1463
   * with rounding according to the given MathContext.
1464
   * @param mc the MathContext
1465
   * @return the new BigDecimal
1466
   */
1467
  public BigDecimal abs(MathContext mc)
1468
  {
1469
    BigDecimal result = abs();
1470
    result = result.round(mc);
1471
    return result;
1472
  }
1473
 
1474
  /**
1475
   * Returns the size of a unit in the last place of this BigDecimal.  This
1476
   * returns a BigDecimal with [unscaledValue, scale] = [1, this.scale()].
1477
   * @return the size of a unit in the last place of <code>this</code>.
1478
   * @since 1.5
1479
   */
1480
  public BigDecimal ulp()
1481
  {
1482
    return new BigDecimal(BigInteger.ONE, scale);
1483
  }
1484
 
1485
  /**
1486
   * Converts this BigDecimal to a long value.
1487
   * @return the long value
1488
   * @throws ArithmeticException if rounding occurs or if overflow occurs
1489
   * @since 1.5
1490
   */
1491
  public long longValueExact()
1492
  {
1493
    // Set scale will throw an exception if rounding occurs.
1494
    BigDecimal temp = setScale(0, ROUND_UNNECESSARY);
1495
    BigInteger tempVal = temp.intVal;
1496
    // Check for overflow.
1497
    long result = intVal.longValue();
1498
    if (tempVal.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 1
1499
        || (result < 0 && signum() == 1) || (result > 0 && signum() == -1))
1500
      throw new ArithmeticException("this BigDecimal is too " +
1501
            "large to fit into the return type");
1502
 
1503
    return intVal.longValue();
1504
  }
1505
 
1506
  /**
1507
   * Converts this BigDecimal into an int by first calling longValueExact
1508
   * and then checking that the <code>long</code> returned from that
1509
   * method fits into an <code>int</code>.
1510
   * @return an int whose value is <code>this</code>
1511
   * @throws ArithmeticException if this BigDecimal has a fractional part
1512
   * or is too large to fit into an int.
1513
   * @since 1.5
1514
   */
1515
  public int intValueExact()
1516
  {
1517
    long temp = longValueExact();
1518
    int result = (int)temp;
1519
    if (result != temp)
1520
      throw new ArithmeticException ("this BigDecimal cannot fit into an int");
1521
    return result;
1522
  }
1523
 
1524
  /**
1525
   * Converts this BigDecimal into a byte by first calling longValueExact
1526
   * and then checking that the <code>long</code> returned from that
1527
   * method fits into a <code>byte</code>.
1528
   * @return a byte whose value is <code>this</code>
1529
   * @throws ArithmeticException if this BigDecimal has a fractional part
1530
   * or is too large to fit into a byte.
1531
   * @since 1.5
1532
   */
1533
  public byte byteValueExact()
1534
  {
1535
    long temp = longValueExact();
1536
    byte result = (byte)temp;
1537
    if (result != temp)
1538
      throw new ArithmeticException ("this BigDecimal cannot fit into a byte");
1539
    return result;
1540
  }
1541
 
1542
  /**
1543
   * Converts this BigDecimal into a short by first calling longValueExact
1544
   * and then checking that the <code>long</code> returned from that
1545
   * method fits into a <code>short</code>.
1546
   * @return a short whose value is <code>this</code>
1547
   * @throws ArithmeticException if this BigDecimal has a fractional part
1548
   * or is too large to fit into a short.
1549
   * @since 1.5
1550
   */
1551
  public short shortValueExact()
1552
  {
1553
    long temp = longValueExact();
1554
    short result = (short)temp;
1555
    if (result != temp)
1556
      throw new ArithmeticException ("this BigDecimal cannot fit into a short");
1557
    return result;
1558
  }
1559
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.