BigDecimal.java 49 KB

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