PageRenderTime 62ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/JavApi/java/math/BigDecimal.cs

#
C# | 3036 lines | 1445 code | 164 blank | 1427 comment | 459 complexity | e336d87ccc04bf8517a4b6b2029237be MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Licensed under the Apache License, Version 2.0 (the "License");
  3. * you may not use this file except in compliance with the License.
  4. * You may obtain a copy of the License at
  5. *
  6. * http://www.apache.org/licenses/LICENSE-2.0
  7. *
  8. * Unless required by applicable law or agreed to in writing, software
  9. * distributed under the License is distributed on an "AS IS" BASIS,
  10. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. * See the License for the specific language governing permissions and
  12. * limitations under the License.
  13. *
  14. */
  15. using System;
  16. using System.Text;
  17. using java = biz.ritter.javapi;
  18. namespace biz.ritter.javapi.math
  19. {
  20. /**
  21. * This class represents immutable arbitrary precision decimal numbers. Each
  22. * {@code BigDecimal} instance is represented with a unscaled arbitrary
  23. * precision mantissa (the unscaled value) and a scale. The value of the {@code
  24. * BigDecimal} is {@code unscaledValue} 10^(-{@code scale}).
  25. */
  26. [Serializable]
  27. public class BigDecimal : java.lang.Number, java.lang.Comparable<BigDecimal>, java.io.Serializable {
  28. /**
  29. * The constant zero as a {@code BigDecimal}.
  30. */
  31. public static readonly BigDecimal ZERO = new BigDecimal(0, 0);
  32. /**
  33. * The constant one as a {@code BigDecimal}.
  34. */
  35. public static readonly BigDecimal ONE = new BigDecimal(1, 0);
  36. /**
  37. * The constant ten as a {@code BigDecimal}.
  38. */
  39. public static readonly BigDecimal TEN = new BigDecimal(10, 0);
  40. /**
  41. * Rounding mode where positive values are rounded towards positive infinity
  42. * and negative values towards negative infinity.
  43. *
  44. * @see RoundingMode#UP
  45. */
  46. public const int ROUND_UP = 0;
  47. /**
  48. * Rounding mode where the values are rounded towards zero.
  49. *
  50. * @see RoundingMode#DOWN
  51. */
  52. public const int ROUND_DOWN = 1;
  53. /**
  54. * Rounding mode to round towards positive infinity. For positive values
  55. * this rounding mode behaves as {@link #ROUND_UP}, for negative values as
  56. * {@link #ROUND_DOWN}.
  57. *
  58. * @see RoundingMode#CEILING
  59. */
  60. public const int ROUND_CEILING = 2;
  61. /**
  62. * Rounding mode to round towards negative infinity. For positive values
  63. * this rounding mode behaves as {@link #ROUND_DOWN}, for negative values as
  64. * {@link #ROUND_UP}.
  65. *
  66. * @see RoundingMode#FLOOR
  67. */
  68. public const int ROUND_FLOOR = 3;
  69. /**
  70. * Rounding mode where values are rounded towards the nearest neighbor.
  71. * Ties are broken by rounding up.
  72. *
  73. * @see RoundingMode#HALF_UP
  74. */
  75. public const int ROUND_HALF_UP = 4;
  76. /**
  77. * Rounding mode where values are rounded towards the nearest neighbor.
  78. * Ties are broken by rounding down.
  79. *
  80. * @see RoundingMode#HALF_DOWN
  81. */
  82. public const int ROUND_HALF_DOWN = 5;
  83. /**
  84. * Rounding mode where values are rounded towards the nearest neighbor.
  85. * Ties are broken by rounding to the even neighbor.
  86. *
  87. * @see RoundingMode#HALF_EVEN
  88. */
  89. public const int ROUND_HALF_EVEN = 6;
  90. /**
  91. * Rounding mode where the rounding operations throws an {@code
  92. * ArithmeticException} for the case that rounding is necessary, i.e. for
  93. * the case that the value cannot be represented exactly.
  94. *
  95. * @see RoundingMode#UNNECESSARY
  96. */
  97. public const int ROUND_UNNECESSARY = 7;
  98. /** This is the serialVersionUID used by the sun implementation. */
  99. private static readonly long serialVersionUID = 6108874887143696463L;
  100. /** The double closer to <code>Log10(2)</code>. */
  101. private static readonly double LOG10_2 = 0.3010299956639812;
  102. /** The <code>String</code> representation is cached. */
  103. [NonSerialized]
  104. private String toStringImage = null;
  105. /** Cache for the hash code. */
  106. [NonSerialized]
  107. private int hashCode = 0;
  108. /**
  109. * An array with powers of five that fit in the type <code>long</code>
  110. * (<code>5^0,5^1,...,5^27</code>).
  111. */
  112. private static readonly BigInteger[] FIVE_POW;
  113. /**
  114. * An array with powers of ten that fit in the type <code>long</code>
  115. * (<code>10^0,10^1,...,10^18</code>).
  116. */
  117. private static readonly BigInteger []TEN_POW;
  118. /**
  119. * An array with powers of ten that fit in the type <code>long</code>
  120. * (<code>10^0,10^1,...,10^18</code>).
  121. */
  122. private static readonly long[] LONG_TEN_POW = new long[]
  123. { 1L,
  124. 10L,
  125. 100L,
  126. 1000L,
  127. 10000L,
  128. 100000L,
  129. 1000000L,
  130. 10000000L,
  131. 100000000L,
  132. 1000000000L,
  133. 10000000000L,
  134. 100000000000L,
  135. 1000000000000L,
  136. 10000000000000L,
  137. 100000000000000L,
  138. 1000000000000000L,
  139. 10000000000000000L,
  140. 100000000000000000L,
  141. 1000000000000000000L, };
  142. private static readonly long[] LONG_FIVE_POW = new long[]
  143. { 1L,
  144. 5L,
  145. 25L,
  146. 125L,
  147. 625L,
  148. 3125L,
  149. 15625L,
  150. 78125L,
  151. 390625L,
  152. 1953125L,
  153. 9765625L,
  154. 48828125L,
  155. 244140625L,
  156. 1220703125L,
  157. 6103515625L,
  158. 30517578125L,
  159. 152587890625L,
  160. 762939453125L,
  161. 3814697265625L,
  162. 19073486328125L,
  163. 95367431640625L,
  164. 476837158203125L,
  165. 2384185791015625L,
  166. 11920928955078125L,
  167. 59604644775390625L,
  168. 298023223876953125L,
  169. 1490116119384765625L,
  170. 7450580596923828125L, };
  171. private static readonly int[] LONG_FIVE_POW_BIT_LENGTH = new int[LONG_FIVE_POW.Length];
  172. private static readonly int[] LONG_TEN_POW_BIT_LENGTH = new int[LONG_TEN_POW.Length];
  173. private static readonly int BI_SCALED_BY_ZERO_LENGTH = 11;
  174. /**
  175. * An array with the first <code>BigInteger</code> scaled by zero.
  176. * (<code>[0,0],[1,0],...,[10,0]</code>).
  177. */
  178. private static readonly BigDecimal[] BI_SCALED_BY_ZERO = new BigDecimal[BI_SCALED_BY_ZERO_LENGTH];
  179. /**
  180. * An array with the zero number scaled by the first positive scales.
  181. * (<code>0*10^0, 0*10^1, ..., 0*10^10</code>).
  182. */
  183. private static readonly BigDecimal []ZERO_SCALED_BY = new BigDecimal[11];
  184. /** An array filled with characters <code>'0'</code>. */
  185. private static readonly char[] CH_ZEROS = new char[100];
  186. static BigDecimal() {
  187. // To fill all static arrays.
  188. int i = 0;
  189. for (; i < ZERO_SCALED_BY.Length; i++) {
  190. BI_SCALED_BY_ZERO[i] = new BigDecimal(i, 0);
  191. ZERO_SCALED_BY[i] = new BigDecimal(0, i);
  192. CH_ZEROS[i] = '0';
  193. }
  194. for (; i < CH_ZEROS.Length; i++) {
  195. CH_ZEROS[i] = '0';
  196. }
  197. for(int j=0; j<LONG_FIVE_POW_BIT_LENGTH.Length; j++) {
  198. LONG_FIVE_POW_BIT_LENGTH[j] = bitLength(LONG_FIVE_POW[j]);
  199. }
  200. for(int j=0; j<LONG_TEN_POW_BIT_LENGTH.Length; j++) {
  201. LONG_TEN_POW_BIT_LENGTH[j] = bitLength(LONG_TEN_POW[j]);
  202. }
  203. // Taking the references of useful powers.
  204. TEN_POW = Multiplication.bigTenPows;
  205. FIVE_POW = Multiplication.bigFivePows;
  206. }
  207. /**
  208. * The arbitrary precision integer (unscaled value) in the internal
  209. * representation of {@code BigDecimal}.
  210. */
  211. private BigInteger intVal;
  212. [NonSerialized]
  213. private int bitLengthJ;
  214. [NonSerialized]
  215. private long smallValue;
  216. /**
  217. * The 32-bit integer scale in the internal representation of {@code BigDecimal}.
  218. */
  219. private int scaleJ;
  220. /**
  221. * Represent the number of decimal digits in the unscaled value. This
  222. * precision is calculated the first time, and used in the following calls
  223. * of method <code>precision()</code>. Note that some call to the private
  224. * method <code>inplaceRound()</code> could update this field.
  225. *
  226. * @see #precision()
  227. * @see #inplaceRound(MathContext)
  228. */
  229. [NonSerialized]
  230. private int precisionJ = 0;
  231. private BigDecimal(long smallValue, int scale){
  232. this.smallValue = smallValue;
  233. this.scaleJ = scale;
  234. this.bitLengthJ = bitLength(smallValue);
  235. }
  236. private BigDecimal(int smallValue, int scale){
  237. this.smallValue = smallValue;
  238. this.scaleJ = scale;
  239. this.bitLengthJ = bitLength(smallValue);
  240. }
  241. /**
  242. * Constructs a new {@code BigDecimal} instance from a string representation
  243. * given as a character array.
  244. *
  245. * @param in
  246. * array of characters containing the string representation of
  247. * this {@code BigDecimal}.
  248. * @param offset
  249. * first index to be copied.
  250. * @param len
  251. * number of characters to be used.
  252. * @throws NullPointerException
  253. * if {@code in == null}.
  254. * @throws NumberFormatException
  255. * if {@code offset < 0} or {@code len <= 0} or {@code
  256. * offset+len-1 < 0} or {@code offset+len-1 >= in.length}.
  257. * @throws NumberFormatException
  258. * if in does not contain a valid string representation of a big
  259. * decimal.
  260. */
  261. public BigDecimal(char[] inJ, int offset, int len) {
  262. int begin = offset; // first index to be copied
  263. int last = offset + (len - 1); // last index to be copied
  264. String scaleString = null; // buffer for scale
  265. StringBuilder unscaledBuffer; // buffer for unscaled value
  266. long newScale; // the new scale
  267. if (inJ == null) {
  268. throw new java.lang.NullPointerException();
  269. }
  270. if ((last >= inJ.Length) || (offset < 0) || (len <= 0) || (last < 0)) {
  271. throw new java.lang.NumberFormatException();
  272. }
  273. unscaledBuffer = new StringBuilder(len);
  274. int bufLength = 0;
  275. // To skip a possible '+' symbol
  276. if ((offset <= last) && (inJ[offset] == '+')) {
  277. offset++;
  278. begin++;
  279. }
  280. int counter = 0;
  281. bool wasNonZero = false;
  282. // Accumulating all digits until a possible decimal point
  283. for (; (offset <= last) && (inJ[offset] != '.')
  284. && (inJ[offset] != 'e') && (inJ[offset] != 'E'); offset++) {
  285. if (!wasNonZero) {
  286. if (inJ[offset] == '0') {
  287. counter++;
  288. } else {
  289. wasNonZero = true;
  290. }
  291. }
  292. }
  293. unscaledBuffer.Append(inJ, begin, offset - begin);
  294. bufLength += offset - begin;
  295. // A decimal point was found
  296. if ((offset <= last) && (inJ[offset] == '.')) {
  297. offset++;
  298. // Accumulating all digits until a possible exponent
  299. begin = offset;
  300. for (; (offset <= last) && (inJ[offset] != 'e')
  301. && (inJ[offset] != 'E'); offset++) {
  302. if (!wasNonZero) {
  303. if (inJ[offset] == '0') {
  304. counter++;
  305. } else {
  306. wasNonZero = true;
  307. }
  308. }
  309. }
  310. scaleJ = offset - begin;
  311. bufLength +=scaleJ;
  312. unscaledBuffer.Append(inJ, begin, scaleJ);
  313. } else {
  314. scaleJ = 0;
  315. }
  316. // An exponent was found
  317. if ((offset <= last) && ((inJ[offset] == 'e') || (inJ[offset] == 'E'))) {
  318. offset++;
  319. // Checking for a possible sign of scale
  320. begin = offset;
  321. if ((offset <= last) && (inJ[offset] == '+')) {
  322. offset++;
  323. if ((offset <= last) && (inJ[offset] != '-')) {
  324. begin++;
  325. }
  326. }
  327. // Accumulating all remaining digits
  328. scaleString = java.lang.StringJ.valueOf(inJ, begin, last + 1 - begin).ToString();
  329. // Checking if the scale is defined
  330. newScale = (long)scaleJ - java.lang.Integer.parseInt(scaleString);
  331. scaleJ = (int)newScale;
  332. if (newScale != scaleJ) {
  333. // math.02=Scale out of range.
  334. throw new java.lang.NumberFormatException("Scale out of range."); //$NON-NLS-1$
  335. }
  336. }
  337. // Parsing the unscaled value
  338. if (bufLength < 19) {
  339. smallValue = java.lang.Long.parseLong(unscaledBuffer.toString());
  340. bitLengthJ = bitLength(smallValue);
  341. } else {
  342. setUnscaledValue(new BigInteger(unscaledBuffer.toString()));
  343. }
  344. precisionJ = unscaledBuffer.Length - counter;
  345. if (unscaledBuffer[0] == '-') {
  346. precisionJ --;
  347. }
  348. }
  349. /**
  350. * Constructs a new {@code BigDecimal} instance from a string representation
  351. * given as a character array.
  352. *
  353. * @param in
  354. * array of characters containing the string representation of
  355. * this {@code BigDecimal}.
  356. * @param offset
  357. * first index to be copied.
  358. * @param len
  359. * number of characters to be used.
  360. * @param mc
  361. * rounding mode and precision for the result of this operation.
  362. * @throws NullPointerException
  363. * if {@code in == null}.
  364. * @throws NumberFormatException
  365. * if {@code offset < 0} or {@code len <= 0} or {@code
  366. * offset+len-1 < 0} or {@code offset+len-1 >= in.length}.
  367. * @throws NumberFormatException
  368. * if {@code in} does not contain a valid string representation
  369. * of a big decimal.
  370. * @throws ArithmeticException
  371. * if {@code mc.precision > 0} and {@code mc.roundingMode ==
  372. * UNNECESSARY} and the new big decimal cannot be represented
  373. * within the given precision without rounding.
  374. */
  375. public BigDecimal(char[] inJ, int offset, int len, MathContext mc) :this(inJ, offset, len){
  376. inplaceRound(mc);
  377. }
  378. /**
  379. * Constructs a new {@code BigDecimal} instance from a string representation
  380. * given as a character array.
  381. *
  382. * @param in
  383. * array of characters containing the string representation of
  384. * this {@code BigDecimal}.
  385. * @throws NullPointerException
  386. * if {@code in == null}.
  387. * @throws NumberFormatException
  388. * if {@code in} does not contain a valid string representation
  389. * of a big decimal.
  390. */
  391. public BigDecimal(char[] inJ) :this(inJ, 0, inJ.Length){
  392. }
  393. /**
  394. * Constructs a new {@code BigDecimal} instance from a string representation
  395. * given as a character array. The result is rounded according to the
  396. * specified math context.
  397. *
  398. * @param in
  399. * array of characters containing the string representation of
  400. * this {@code BigDecimal}.
  401. * @param mc
  402. * rounding mode and precision for the result of this operation.
  403. * @throws NullPointerException
  404. * if {@code in == null}.
  405. * @throws NumberFormatException
  406. * if {@code in} does not contain a valid string representation
  407. * of a big decimal.
  408. * @throws ArithmeticException
  409. * if {@code mc.precision > 0} and {@code mc.roundingMode ==
  410. * UNNECESSARY} and the new big decimal cannot be represented
  411. * within the given precision without rounding.
  412. */
  413. public BigDecimal(char[] inJ, MathContext mc) :this(inJ, 0, inJ.Length){
  414. inplaceRound(mc);
  415. }
  416. /**
  417. * Constructs a new {@code BigDecimal} instance from a string
  418. * representation.
  419. *
  420. * @param val
  421. * string containing the string representation of this {@code
  422. * BigDecimal}.
  423. * @throws NumberFormatException
  424. * if {@code val} does not contain a valid string representation
  425. * of a big decimal.
  426. */
  427. public BigDecimal(String val) :this(val.toCharArray(), 0, val.length()){
  428. }
  429. /**
  430. * Constructs a new {@code BigDecimal} instance from a string
  431. * representation. The result is rounded according to the specified math
  432. * context.
  433. *
  434. * @param val
  435. * string containing the string representation of this {@code
  436. * BigDecimal}.
  437. * @param mc
  438. * rounding mode and precision for the result of this operation.
  439. * @throws NumberFormatException
  440. * if {@code val} does not contain a valid string representation
  441. * of a big decimal.
  442. * @throws ArithmeticException
  443. * if {@code mc.precision > 0} and {@code mc.roundingMode ==
  444. * UNNECESSARY} and the new big decimal cannot be represented
  445. * within the given precision without rounding.
  446. */
  447. public BigDecimal(String val, MathContext mc) :this(val.toCharArray(), 0, val.length()){
  448. inplaceRound(mc);
  449. }
  450. /**
  451. * Constructs a new {@code BigDecimal} instance from the 64bit double
  452. * {@code val}. The constructed big decimal is equivalent to the given
  453. * double. For example, {@code new BigDecimal(0.1)} is equal to {@code
  454. * 0.1000000000000000055511151231257827021181583404541015625}. This happens
  455. * as {@code 0.1} cannot be represented exactly in binary.
  456. * <p>
  457. * To generate a big decimal instance which is equivalent to {@code 0.1} use
  458. * the {@code BigDecimal(String)} constructor.
  459. *
  460. * @param val
  461. * double value to be converted to a {@code BigDecimal} instance.
  462. * @throws NumberFormatException
  463. * if {@code val} is infinity or not a number.
  464. */
  465. public BigDecimal(double val) {
  466. if (java.lang.Double.isInfinite(val) || java.lang.Double.isNaN(val)) {
  467. // math.03=Infinity or NaN
  468. throw new java.lang.NumberFormatException("Infinity or NaN"); //$NON-NLS-1$
  469. }
  470. long bits = java.lang.Double.doubleToLongBits(val); // IEEE-754
  471. long mantisa;
  472. int trailingZeros;
  473. // Extracting the exponent, note that the bias is 1023
  474. scaleJ = 1075 - (int)((bits >> 52) & 0x7FFL);
  475. // Extracting the 52 bits of the mantisa.
  476. mantisa = (scaleJ == 1075) ? (bits & 0xFFFFFFFFFFFFFL) << 1
  477. : (bits & 0xFFFFFFFFFFFFFL) | 0x10000000000000L;
  478. if (mantisa == 0) {
  479. scaleJ = 0;
  480. precisionJ = 1;
  481. }
  482. // To simplify all factors '2' in the mantisa
  483. if (scaleJ > 0) {
  484. trailingZeros = java.lang.Math.min(scaleJ, java.lang.Long.numberOfTrailingZeros(mantisa));
  485. mantisa= java.dotnet.lang.Operator.shiftRightUnsignet(mantisa, trailingZeros);
  486. scaleJ -= trailingZeros;
  487. }
  488. // Calculating the new unscaled value and the new scale
  489. if((bits >> 63) != 0) {
  490. mantisa = -mantisa;
  491. }
  492. int mantisaBits = bitLength(mantisa);
  493. if (scaleJ < 0) {
  494. bitLengthJ = mantisaBits == 0 ? 0 : mantisaBits - scaleJ;
  495. if(bitLengthJ < 64) {
  496. smallValue = mantisa << (-scaleJ);
  497. } else {
  498. intVal = BigInteger.valueOf(mantisa).shiftLeft(-scaleJ);
  499. }
  500. scaleJ = 0;
  501. } else if (scaleJ > 0) {
  502. // m * 2^e = (m * 5^(-e)) * 10^e
  503. if(scaleJ < LONG_FIVE_POW.Length
  504. && mantisaBits+LONG_FIVE_POW_BIT_LENGTH[scaleJ] < 64) {
  505. smallValue = mantisa * LONG_FIVE_POW[scaleJ];
  506. bitLengthJ = bitLength(smallValue);
  507. } else {
  508. setUnscaledValue(Multiplication.multiplyByFivePow(BigInteger.valueOf(mantisa), scaleJ));
  509. }
  510. } else { // scale == 0
  511. smallValue = mantisa;
  512. bitLengthJ = mantisaBits;
  513. }
  514. }
  515. /**
  516. * Constructs a new {@code BigDecimal} instance from the 64bit double
  517. * {@code val}. The constructed big decimal is equivalent to the given
  518. * double. For example, {@code new BigDecimal(0.1)} is equal to {@code
  519. * 0.1000000000000000055511151231257827021181583404541015625}. This happens
  520. * as {@code 0.1} cannot be represented exactly in binary.
  521. * <p>
  522. * To generate a big decimal instance which is equivalent to {@code 0.1} use
  523. * the {@code BigDecimal(String)} constructor.
  524. *
  525. * @param val
  526. * double value to be converted to a {@code BigDecimal} instance.
  527. * @param mc
  528. * rounding mode and precision for the result of this operation.
  529. * @throws NumberFormatException
  530. * if {@code val} is infinity or not a number.
  531. * @throws ArithmeticException
  532. * if {@code mc.precision > 0} and {@code mc.roundingMode ==
  533. * UNNECESSARY} and the new big decimal cannot be represented
  534. * within the given precision without rounding.
  535. */
  536. public BigDecimal(double val, MathContext mc) :this(val){
  537. inplaceRound(mc);
  538. }
  539. /**
  540. * Constructs a new {@code BigDecimal} instance from the given big integer
  541. * {@code val}. The scale of the result is {@code 0}.
  542. *
  543. * @param val
  544. * {@code BigInteger} value to be converted to a {@code
  545. * BigDecimal} instance.
  546. */
  547. public BigDecimal(BigInteger val):this(val, 0){
  548. }
  549. /**
  550. * Constructs a new {@code BigDecimal} instance from the given big integer
  551. * {@code val}. The scale of the result is {@code 0}.
  552. *
  553. * @param val
  554. * {@code BigInteger} value to be converted to a {@code
  555. * BigDecimal} instance.
  556. * @param mc
  557. * rounding mode and precision for the result of this operation.
  558. * @throws ArithmeticException
  559. * if {@code mc.precision > 0} and {@code mc.roundingMode ==
  560. * UNNECESSARY} and the new big decimal cannot be represented
  561. * within the given precision without rounding.
  562. */
  563. public BigDecimal(BigInteger val, MathContext mc) :this(val){
  564. inplaceRound(mc);
  565. }
  566. /**
  567. * Constructs a new {@code BigDecimal} instance from a given unscaled value
  568. * {@code unscaledVal} and a given scale. The value of this instance is
  569. * {@code unscaledVal} 10^(-{@code scale}).
  570. *
  571. * @param unscaledVal
  572. * {@code BigInteger} representing the unscaled value of this
  573. * {@code BigDecimal} instance.
  574. * @param scale
  575. * scale of this {@code BigDecimal} instance.
  576. * @throws NullPointerException
  577. * if {@code unscaledVal == null}.
  578. */
  579. public BigDecimal(BigInteger unscaledVal, int scale) {
  580. if (unscaledVal == null) {
  581. throw new java.lang.NullPointerException();
  582. }
  583. this.scaleJ = scale;
  584. setUnscaledValue(unscaledVal);
  585. }
  586. /**
  587. * Constructs a new {@code BigDecimal} instance from a given unscaled value
  588. * {@code unscaledVal} and a given scale. The value of this instance is
  589. * {@code unscaledVal} 10^(-{@code scale}). The result is rounded according
  590. * to the specified math context.
  591. *
  592. * @param unscaledVal
  593. * {@code BigInteger} representing the unscaled value of this
  594. * {@code BigDecimal} instance.
  595. * @param scale
  596. * scale of this {@code BigDecimal} instance.
  597. * @param mc
  598. * rounding mode and precision for the result of this operation.
  599. * @throws ArithmeticException
  600. * if {@code mc.precision > 0} and {@code mc.roundingMode ==
  601. * UNNECESSARY} and the new big decimal cannot be represented
  602. * within the given precision without rounding.
  603. * @throws NullPointerException
  604. * if {@code unscaledVal == null}.
  605. */
  606. public BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) :this(unscaledVal, scale){
  607. inplaceRound(mc);
  608. }
  609. /**
  610. * Constructs a new {@code BigDecimal} instance from the given int
  611. * {@code val}. The scale of the result is 0.
  612. *
  613. * @param val
  614. * int value to be converted to a {@code BigDecimal} instance.
  615. */
  616. public BigDecimal(int val) :this(val,0){
  617. }
  618. /**
  619. * Constructs a new {@code BigDecimal} instance from the given int {@code
  620. * val}. The scale of the result is {@code 0}. The result is rounded
  621. * according to the specified math context.
  622. *
  623. * @param val
  624. * int value to be converted to a {@code BigDecimal} instance.
  625. * @param mc
  626. * rounding mode and precision for the result of this operation.
  627. * @throws ArithmeticException
  628. * if {@code mc.precision > 0} and {@code c.roundingMode ==
  629. * UNNECESSARY} and the new big decimal cannot be represented
  630. * within the given precision without rounding.
  631. */
  632. public BigDecimal(int val, MathContext mc) :this(val,0){
  633. inplaceRound(mc);
  634. }
  635. /**
  636. * Constructs a new {@code BigDecimal} instance from the given long {@code
  637. * val}. The scale of the result is {@code 0}.
  638. *
  639. * @param val
  640. * long value to be converted to a {@code BigDecimal} instance.
  641. */
  642. public BigDecimal(long val) :this(val,0){
  643. }
  644. /**
  645. * Constructs a new {@code BigDecimal} instance from the given long {@code
  646. * val}. The scale of the result is {@code 0}. The result is rounded
  647. * according to the specified math context.
  648. *
  649. * @param val
  650. * long value to be converted to a {@code BigDecimal} instance.
  651. * @param mc
  652. * rounding mode and precision for the result of this operation.
  653. * @throws ArithmeticException
  654. * if {@code mc.precision > 0} and {@code mc.roundingMode ==
  655. * UNNECESSARY} and the new big decimal cannot be represented
  656. * within the given precision without rounding.
  657. */
  658. public BigDecimal(long val, MathContext mc) :this(val){
  659. inplaceRound(mc);
  660. }
  661. /* Public Methods */
  662. /**
  663. * Returns a new {@code BigDecimal} instance whose value is equal to {@code
  664. * unscaledVal} 10^(-{@code scale}). The scale of the result is {@code
  665. * scale}, and its unscaled value is {@code unscaledVal}.
  666. *
  667. * @param unscaledVal
  668. * unscaled value to be used to construct the new {@code
  669. * BigDecimal}.
  670. * @param scale
  671. * scale to be used to construct the new {@code BigDecimal}.
  672. * @return {@code BigDecimal} instance with the value {@code unscaledVal}*
  673. * 10^(-{@code unscaledVal}).
  674. */
  675. public static BigDecimal valueOf(long unscaledVal, int scale) {
  676. if (scale == 0) {
  677. return valueOf(unscaledVal);
  678. }
  679. if ((unscaledVal == 0) && (scale >= 0)
  680. && (scale < ZERO_SCALED_BY.Length)) {
  681. return ZERO_SCALED_BY[scale];
  682. }
  683. return new BigDecimal(unscaledVal, scale);
  684. }
  685. /**
  686. * Returns a new {@code BigDecimal} instance whose value is equal to {@code
  687. * unscaledVal}. The scale of the result is {@code 0}, and its unscaled
  688. * value is {@code unscaledVal}.
  689. *
  690. * @param unscaledVal
  691. * value to be converted to a {@code BigDecimal}.
  692. * @return {@code BigDecimal} instance with the value {@code unscaledVal}.
  693. */
  694. public static BigDecimal valueOf(long unscaledVal) {
  695. if ((unscaledVal >= 0) && (unscaledVal < BI_SCALED_BY_ZERO_LENGTH)) {
  696. return BI_SCALED_BY_ZERO[(int)unscaledVal];
  697. }
  698. return new BigDecimal(unscaledVal,0);
  699. }
  700. /**
  701. * Returns a new {@code BigDecimal} instance whose value is equal to {@code
  702. * val}. The new decimal is constructed as if the {@code BigDecimal(String)}
  703. * constructor is called with an argument which is equal to {@code
  704. * Double.toString(val)}. For example, {@code valueOf("0.1")} is converted to
  705. * (unscaled=1, scale=1), although the double {@code 0.1} cannot be
  706. * represented exactly as a double value. In contrast to that, a new {@code
  707. * BigDecimal(0.1)} instance has the value {@code
  708. * 0.1000000000000000055511151231257827021181583404541015625} with an
  709. * unscaled value {@code 1000000000000000055511151231257827021181583404541015625}
  710. * and the scale {@code 55}.
  711. *
  712. * @param val
  713. * double value to be converted to a {@code BigDecimal}.
  714. * @return {@code BigDecimal} instance with the value {@code val}.
  715. * @throws NumberFormatException
  716. * if {@code val} is infinite or {@code val} is not a number
  717. */
  718. public static BigDecimal valueOf(double val) {
  719. if (java.lang.Double.isInfinite(val) || java.lang.Double.isNaN(val)) {
  720. // math.03=Infinity or NaN
  721. throw new java.lang.NumberFormatException("Infinity or NaN"); //$NON-NLS-1$
  722. }
  723. return new BigDecimal(java.lang.Double.toString(val));
  724. }
  725. /**
  726. * Returns a new {@code BigDecimal} whose value is {@code this + augend}.
  727. * The scale of the result is the maximum of the scales of the two
  728. * arguments.
  729. *
  730. * @param augend
  731. * value to be added to {@code this}.
  732. * @return {@code this + augend}.
  733. * @throws NullPointerException
  734. * if {@code augend == null}.
  735. */
  736. public BigDecimal add(BigDecimal augend) {
  737. int diffScale = this.scaleJ - augend.scaleJ;
  738. // Fast return when some operand is zero
  739. if (this.isZero()) {
  740. if (diffScale <= 0) {
  741. return augend;
  742. }
  743. if (augend.isZero()) {
  744. return this;
  745. }
  746. } else if (augend.isZero()) {
  747. if (diffScale >= 0) {
  748. return this;
  749. }
  750. }
  751. // Let be: this = [u1,s1] and augend = [u2,s2]
  752. if (diffScale == 0) {
  753. // case s1 == s2: [u1 + u2 , s1]
  754. if (java.lang.Math.max(this.bitLengthJ, augend.bitLengthJ) + 1 < 64) {
  755. return valueOf(this.smallValue + augend.smallValue, this.scaleJ);
  756. }
  757. return new BigDecimal(this.getUnscaledValue().add(augend.getUnscaledValue()), this.scaleJ);
  758. } else if (diffScale > 0) {
  759. // case s1 > s2 : [(u1 + u2) * 10 ^ (s1 - s2) , s1]
  760. return addAndMult10(this, augend, diffScale);
  761. } else {// case s2 > s1 : [(u2 + u1) * 10 ^ (s2 - s1) , s2]
  762. return addAndMult10(augend, this, -diffScale);
  763. }
  764. }
  765. private static BigDecimal addAndMult10(BigDecimal thisValue,BigDecimal augend, int diffScale) {
  766. if(diffScale < LONG_TEN_POW.Length &&
  767. java.lang.Math.max(thisValue.bitLengthJ,augend.bitLengthJ+LONG_TEN_POW_BIT_LENGTH[diffScale])+1<64) {
  768. return valueOf(thisValue.smallValue+augend.smallValue*LONG_TEN_POW[diffScale],thisValue.scaleJ);
  769. }
  770. return new BigDecimal(thisValue.getUnscaledValue().add(
  771. Multiplication.multiplyByTenPow(augend.getUnscaledValue(),diffScale)), thisValue.scaleJ);
  772. }
  773. /**
  774. * Returns a new {@code BigDecimal} whose value is {@code this + augend}.
  775. * The result is rounded according to the passed context {@code mc}.
  776. *
  777. * @param augend
  778. * value to be added to {@code this}.
  779. * @param mc
  780. * rounding mode and precision for the result of this operation.
  781. * @return {@code this + augend}.
  782. * @throws NullPointerException
  783. * if {@code augend == null} or {@code mc == null}.
  784. */
  785. public BigDecimal add(BigDecimal augend, MathContext mc) {
  786. BigDecimal larger; // operand with the largest unscaled value
  787. BigDecimal smaller; // operand with the smallest unscaled value
  788. BigInteger tempBI;
  789. long diffScale = (long)this.scaleJ - augend.scaleJ;
  790. int largerSignum;
  791. // Some operand is zero or the precision is infinity
  792. if ((augend.isZero()) || (this.isZero())
  793. || (mc.getPrecision() == 0)) {
  794. return add(augend).round(mc);
  795. }
  796. // Cases where there is room for optimizations
  797. if (this.aproxPrecision() < diffScale - 1) {
  798. larger = augend;
  799. smaller = this;
  800. } else if (augend.aproxPrecision() < -diffScale - 1) {
  801. larger = this;
  802. smaller = augend;
  803. } else {// No optimization is done
  804. return add(augend).round(mc);
  805. }
  806. if (mc.getPrecision() >= larger.aproxPrecision()) {
  807. // No optimization is done
  808. return add(augend).round(mc);
  809. }
  810. // Cases where it's unnecessary to add two numbers with very different scales
  811. largerSignum = larger.signum();
  812. if (largerSignum == smaller.signum()) {
  813. tempBI = Multiplication.multiplyByPositiveInt(larger.getUnscaledValue(),10)
  814. .add(BigInteger.valueOf(largerSignum));
  815. } else {
  816. tempBI = larger.getUnscaledValue().subtract(
  817. BigInteger.valueOf(largerSignum));
  818. tempBI = Multiplication.multiplyByPositiveInt(tempBI,10)
  819. .add(BigInteger.valueOf(largerSignum * 9));
  820. }
  821. // Rounding the improved adding
  822. larger = new BigDecimal(tempBI, larger.scaleJ + 1);
  823. return larger.round(mc);
  824. }
  825. /**
  826. * Returns a new {@code BigDecimal} whose value is {@code this - subtrahend}.
  827. * The scale of the result is the maximum of the scales of the two arguments.
  828. *
  829. * @param subtrahend
  830. * value to be subtracted from {@code this}.
  831. * @return {@code this - subtrahend}.
  832. * @throws NullPointerException
  833. * if {@code subtrahend == null}.
  834. */
  835. public BigDecimal subtract(BigDecimal subtrahend) {
  836. int diffScale = this.scaleJ - subtrahend.scaleJ;
  837. // Fast return when some operand is zero
  838. if (this.isZero()) {
  839. if (diffScale <= 0) {
  840. return subtrahend.negate();
  841. }
  842. if (subtrahend.isZero()) {
  843. return this;
  844. }
  845. } else if (subtrahend.isZero()) {
  846. if (diffScale >= 0) {
  847. return this;
  848. }
  849. }
  850. // Let be: this = [u1,s1] and subtrahend = [u2,s2] so:
  851. if (diffScale == 0) {
  852. // case s1 = s2 : [u1 - u2 , s1]
  853. if (java.lang.Math.max(this.bitLengthJ, subtrahend.bitLengthJ) + 1 < 64) {
  854. return valueOf(this.smallValue - subtrahend.smallValue,this.scaleJ);
  855. }
  856. return new BigDecimal(this.getUnscaledValue().subtract(subtrahend.getUnscaledValue()), this.scaleJ);
  857. } else if (diffScale > 0) {
  858. // case s1 > s2 : [ u1 - u2 * 10 ^ (s1 - s2) , s1 ]
  859. if(diffScale < LONG_TEN_POW.Length &&
  860. java.lang.Math.max(this.bitLengthJ,subtrahend.bitLengthJ+LONG_TEN_POW_BIT_LENGTH[diffScale])+1<64) {
  861. return valueOf(this.smallValue-subtrahend.smallValue*LONG_TEN_POW[diffScale],this.scaleJ);
  862. }
  863. return new BigDecimal(this.getUnscaledValue().subtract(
  864. Multiplication.multiplyByTenPow(subtrahend.getUnscaledValue(),diffScale)), this.scaleJ);
  865. } else {// case s2 > s1 : [ u1 * 10 ^ (s2 - s1) - u2 , s2 ]
  866. diffScale = -diffScale;
  867. if(diffScale < LONG_TEN_POW.Length &&
  868. java.lang.Math.max(this.bitLengthJ+LONG_TEN_POW_BIT_LENGTH[diffScale],subtrahend.bitLengthJ)+1<64) {
  869. return valueOf(this.smallValue*LONG_TEN_POW[diffScale]-subtrahend.smallValue,subtrahend.scaleJ);
  870. }
  871. return new BigDecimal(Multiplication.multiplyByTenPow(this.getUnscaledValue(),diffScale)
  872. .subtract(subtrahend.getUnscaledValue()), subtrahend.scaleJ);
  873. }
  874. }
  875. /**
  876. * Returns a new {@code BigDecimal} whose value is {@code this - subtrahend}.
  877. * The result is rounded according to the passed context {@code mc}.
  878. *
  879. * @param subtrahend
  880. * value to be subtracted from {@code this}.
  881. * @param mc
  882. * rounding mode and precision for the result of this operation.
  883. * @return {@code this - subtrahend}.
  884. * @throws NullPointerException
  885. * if {@code subtrahend == null} or {@code mc == null}.
  886. */
  887. public BigDecimal subtract(BigDecimal subtrahend, MathContext mc) {
  888. long diffScale = subtrahend.scaleJ - (long)this.scaleJ;
  889. int thisSignum;
  890. BigDecimal leftOperand; // it will be only the left operand (this)
  891. BigInteger tempBI;
  892. // Some operand is zero or the precision is infinity
  893. if ((subtrahend.isZero()) || (this.isZero())
  894. || (mc.getPrecision() == 0)) {
  895. return subtract(subtrahend).round(mc);
  896. }
  897. // Now: this != 0 and subtrahend != 0
  898. if (subtrahend.aproxPrecision() < diffScale - 1) {
  899. // Cases where it is unnecessary to subtract two numbers with very different scales
  900. if (mc.getPrecision() < this.aproxPrecision()) {
  901. thisSignum = this.signum();
  902. if (thisSignum != subtrahend.signum()) {
  903. tempBI = Multiplication.multiplyByPositiveInt(this.getUnscaledValue(), 10)
  904. .add(BigInteger.valueOf(thisSignum));
  905. } else {
  906. tempBI = this.getUnscaledValue().subtract(BigInteger.valueOf(thisSignum));
  907. tempBI = Multiplication.multiplyByPositiveInt(tempBI, 10)
  908. .add(BigInteger.valueOf(thisSignum * 9));
  909. }
  910. // Rounding the improved subtracting
  911. leftOperand = new BigDecimal(tempBI, this.scaleJ + 1);
  912. return leftOperand.round(mc);
  913. }
  914. }
  915. // No optimization is done
  916. return subtract(subtrahend).round(mc);
  917. }
  918. /**
  919. * Returns a new {@code BigDecimal} whose value is {@code this *
  920. * multiplicand}. The scale of the result is the sum of the scales of the
  921. * two arguments.
  922. *
  923. * @param multiplicand
  924. * value to be multiplied with {@code this}.
  925. * @return {@code this * multiplicand}.
  926. * @throws NullPointerException
  927. * if {@code multiplicand == null}.
  928. */
  929. public BigDecimal multiply(BigDecimal multiplicand) {
  930. long newScale = (long)this.scaleJ + multiplicand.scaleJ;
  931. if ((this.isZero()) || (multiplicand.isZero())) {
  932. return zeroScaledBy(newScale);
  933. }
  934. /* Let be: this = [u1,s1] and multiplicand = [u2,s2] so:
  935. * this x multiplicand = [ s1 * s2 , s1 + s2 ] */
  936. if(this.bitLengthJ + multiplicand.bitLengthJ < 64) {
  937. return valueOf(this.smallValue*multiplicand.smallValue,toIntScale(newScale));
  938. }
  939. return new BigDecimal(this.getUnscaledValue().multiply(
  940. multiplicand.getUnscaledValue()), toIntScale(newScale));
  941. }
  942. /**
  943. * Returns a new {@code BigDecimal} whose value is {@code this *
  944. * multiplicand}. The result is rounded according to the passed context
  945. * {@code mc}.
  946. *
  947. * @param multiplicand
  948. * value to be multiplied with {@code this}.
  949. * @param mc
  950. * rounding mode and precision for the result of this operation.
  951. * @return {@code this * multiplicand}.
  952. * @throws NullPointerException
  953. * if {@code multiplicand == null} or {@code mc == null}.
  954. */
  955. public BigDecimal multiply(BigDecimal multiplicand, MathContext mc) {
  956. BigDecimal result = multiply(multiplicand);
  957. result.inplaceRound(mc);
  958. return result;
  959. }
  960. /**
  961. * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
  962. * As scale of the result the parameter {@code scale} is used. If rounding
  963. * is required to meet the specified scale, then the specified rounding mode
  964. * {@code roundingMode} is applied.
  965. *
  966. * @param divisor
  967. * value by which {@code this} is divided.
  968. * @param scale
  969. * the scale of the result returned.
  970. * @param roundingMode
  971. * rounding mode to be used to round the result.
  972. * @return {@code this / divisor} rounded according to the given rounding
  973. * mode.
  974. * @throws NullPointerException
  975. * if {@code divisor == null}.
  976. * @throws IllegalArgumentException
  977. * if {@code roundingMode} is not a valid rounding mode.
  978. * @throws ArithmeticException
  979. * if {@code divisor == 0}.
  980. * @throws ArithmeticException
  981. * if {@code roundingMode == ROUND_UNNECESSARY} and rounding is
  982. * necessary according to the given scale.
  983. */
  984. public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) {
  985. return divide(divisor, scale, RoundingMode.valueOf(roundingMode));
  986. }
  987. /**
  988. * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
  989. * As scale of the result the parameter {@code scale} is used. If rounding
  990. * is required to meet the specified scale, then the specified rounding mode
  991. * {@code roundingMode} is applied.
  992. *
  993. * @param divisor
  994. * value by which {@code this} is divided.
  995. * @param scale
  996. * the scale of the result returned.
  997. * @param roundingMode
  998. * rounding mode to be used to round the result.
  999. * @return {@code this / divisor} rounded according to the given rounding
  1000. * mode.
  1001. * @throws NullPointerException
  1002. * if {@code divisor == null} or {@code roundingMode == null}.
  1003. * @throws ArithmeticException
  1004. * if {@code divisor == 0}.
  1005. * @throws ArithmeticException
  1006. * if {@code roundingMode == RoundingMode.UNNECESSAR}Y and
  1007. * rounding is necessary according to the given scale and given
  1008. * precision.
  1009. */
  1010. public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode) {
  1011. // Let be: this = [u1,s1] and divisor = [u2,s2]
  1012. if (roundingMode == null) {
  1013. throw new java.lang.NullPointerException();
  1014. }
  1015. if (divisor.isZero()) {
  1016. // math.04=Division by zero
  1017. throw new java.lang.ArithmeticException("Division by zero"); //$NON-NLS-1$
  1018. }
  1019. long diffScale = ((long)this.scaleJ - divisor.scaleJ) - scale;
  1020. if(this.bitLengthJ < 64 && divisor.bitLengthJ < 64 ) {
  1021. if(diffScale == 0) {
  1022. return dividePrimitiveLongs(this.smallValue,
  1023. divisor.smallValue,
  1024. scale,
  1025. roundingMode );
  1026. } else if(diffScale > 0) {
  1027. if(diffScale < LONG_TEN_POW.Length &&
  1028. divisor.bitLengthJ + LONG_TEN_POW_BIT_LENGTH[(int)diffScale] < 64) {
  1029. return dividePrimitiveLongs(this.smallValue,
  1030. divisor.smallValue*LONG_TEN_POW[(int)diffScale],
  1031. scale,
  1032. roundingMode);
  1033. }
  1034. } else { // diffScale < 0
  1035. if(-diffScale < LONG_TEN_POW.Length &&
  1036. this.bitLengthJ + LONG_TEN_POW_BIT_LENGTH[(int)-diffScale] < 64) {
  1037. return dividePrimitiveLongs(this.smallValue*LONG_TEN_POW[(int)-diffScale],
  1038. divisor.smallValue,
  1039. scale,
  1040. roundingMode);
  1041. }
  1042. }
  1043. }
  1044. BigInteger scaledDividend = this.getUnscaledValue();
  1045. BigInteger scaledDivisor = divisor.getUnscaledValue(); // for scaling of 'u2'
  1046. if (diffScale > 0) {
  1047. // Multiply 'u2' by: 10^((s1 - s2) - scale)
  1048. scaledDivisor = Multiplication.multiplyByTenPow(scaledDivisor, (int)diffScale);
  1049. } else if (diffScale < 0) {
  1050. // Multiply 'u1' by: 10^(scale - (s1 - s2))
  1051. scaledDividend = Multiplication.multiplyByTenPow(scaledDividend, (int)-diffScale);
  1052. }
  1053. return divideBigIntegers(scaledDividend, scaledDivisor, scale, roundingMode);
  1054. }
  1055. private static BigDecimal divideBigIntegers(BigInteger scaledDividend, BigInteger scaledDivisor, int scale, RoundingMode roundingMode) {
  1056. BigInteger[] quotAndRem = scaledDividend.divideAndRemainder(scaledDivisor); // quotient and remainder
  1057. // If after division there is a remainder...
  1058. BigInteger quotient = quotAndRem[0];
  1059. BigInteger remainder = quotAndRem[1];
  1060. if (remainder.signum() == 0) {
  1061. return new BigDecimal(quotient, scale);
  1062. }
  1063. int sign = scaledDividend.signum() * scaledDivisor.signum();
  1064. int compRem; // 'compare to remainder'
  1065. if(scaledDivisor.bitLength() < 63) { // 63 in order to avoid out of long after <<1
  1066. long rem = remainder.longValue();
  1067. long divisor = scaledDivisor.longValue();
  1068. compRem = longCompareTo(java.lang.Math.abs(rem) << 1,java.lang.Math.abs(divisor));
  1069. // To look if there is a carry
  1070. compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0,
  1071. sign * (5 + compRem), roundingMode);
  1072. } else {
  1073. // Checking if: remainder * 2 >= scaledDivisor
  1074. compRem = remainder.abs().shiftLeftOneBit().compareTo(scaledDivisor.abs());
  1075. c

Large files files are truncated, but you can click here to view the full file