1:
37:
38: package ;
39:
40: public class BigDecimal extends Number implements Comparable
41: {
42: private BigInteger intVal;
43: private int scale;
44: private int precision = 0;
45: private static final long serialVersionUID = 6108874887143696463L;
46:
47:
51: public static final BigDecimal ZERO =
52: new BigDecimal (BigInteger.ZERO, 0);
53:
54:
58: public static final BigDecimal ONE =
59: new BigDecimal (BigInteger.ONE, 0);
60:
61:
65: public static final BigDecimal TEN =
66: new BigDecimal (BigInteger.TEN, 0);
67:
68: public static final int ROUND_UP = 0;
69: public static final int ROUND_DOWN = 1;
70: public static final int ROUND_CEILING = 2;
71: public static final int ROUND_FLOOR = 3;
72: public static final int ROUND_HALF_UP = 4;
73: public static final int ROUND_HALF_DOWN = 5;
74: public static final int ROUND_HALF_EVEN = 6;
75: public static final int ROUND_UNNECESSARY = 7;
76:
77:
83: public BigDecimal (int val)
84: {
85: this.intVal = BigInteger.valueOf(val);
86: this.scale = 0;
87: }
88:
89:
98: public BigDecimal (int val, MathContext mc)
99: {
100: this (val);
101: if (mc.getPrecision() != 0)
102: {
103: BigDecimal result = this.round(mc);
104: this.intVal = result.intVal;
105: this.scale = result.scale;
106: this.precision = result.precision;
107: }
108: }
109:
110:
115: public BigDecimal (long val)
116: {
117: this.intVal = BigInteger.valueOf(val);
118: this.scale = 0;
119: }
120:
121:
130: public BigDecimal (long val, MathContext mc)
131: {
132: this(val);
133: if (mc.getPrecision() != 0)
134: {
135: BigDecimal result = this.round(mc);
136: this.intVal = result.intVal;
137: this.scale = result.scale;
138: this.precision = result.precision;
139: }
140: }
141:
142:
153: public BigDecimal (BigInteger num, MathContext mc)
154: {
155: this (num, 0);
156: if (mc.getPrecision() != 0)
157: {
158: BigDecimal result = this.round(mc);
159: this.intVal = result.intVal;
160: this.scale = result.scale;
161: this.precision = result.precision;
162: }
163: }
164:
165:
175: public BigDecimal (String val, MathContext mc)
176: {
177: this (val);
178: if (mc.getPrecision() != 0)
179: {
180: BigDecimal result = this.round(mc);
181: this.intVal = result.intVal;
182: this.scale = result.scale;
183: this.precision = result.precision;
184: }
185: }
186:
187:
192: public BigDecimal (BigInteger num)
193: {
194: this (num, 0);
195: }
196:
197:
203: public BigDecimal (BigInteger num, int scale)
204: {
205: this.intVal = num;
206: this.scale = scale;
207: }
208:
209:
219: public BigDecimal (BigInteger num, int scale, MathContext mc)
220: {
221: this (num, scale);
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:
231:
240: public BigDecimal (double num, MathContext mc)
241: {
242: this (num);
243: if (mc.getPrecision() != 0)
244: {
245: BigDecimal result = this.round(mc);
246: this.intVal = result.intVal;
247: this.scale = result.scale;
248: this.precision = result.precision;
249: }
250: }
251:
252: public BigDecimal (double num) throws NumberFormatException
253: {
254: if (Double.isInfinite (num) || Double.isNaN (num))
255: throw new NumberFormatException ("invalid argument: " + num);
256:
257:
258:
259:
260: final int mantissaBits = 52;
261: final int exponentBits = 11;
262: final long mantMask = (1L << mantissaBits) - 1;
263: final long expMask = (1L << exponentBits) - 1;
264:
265: long bits = Double.doubleToLongBits (num);
266: long mantissa = bits & mantMask;
267: long exponent = (bits >>> mantissaBits) & expMask;
268: boolean denormal = exponent == 0;
269:
270:
271: exponent -= denormal ? 1022 : 1023;
272:
273:
274:
275: exponent -= mantissaBits;
276:
277: if (! denormal)
278: mantissa |= (1L << mantissaBits);
279:
280:
281: while (exponent < 0 && (mantissa & 1) == 0)
282: {
283: ++exponent;
284: mantissa >>= 1;
285: }
286:
287: intVal = BigInteger.valueOf (bits < 0 ? - mantissa : mantissa);
288: if (exponent < 0)
289: {
290:
291:
292:
293: scale = (int) (- exponent);
294: BigInteger mult = BigInteger.valueOf (5).pow (scale);
295: intVal = intVal.multiply (mult);
296: }
297: else
298: {
299: intVal = intVal.shiftLeft ((int) exponent);
300: scale = 0;
301: }
302: }
303:
304:
317: public BigDecimal(char[] in, int offset, int len, MathContext mc)
318: {
319: this(in, offset, len);
320:
321: if (mc.getPrecision() != 0)
322: {
323: BigDecimal temp = this.round(mc);
324: this.intVal = temp.intVal;
325: this.scale = temp.scale;
326: this.precision = temp.precision;
327: }
328: }
329:
330:
341: public BigDecimal(char[] in, MathContext mc)
342: {
343: this(in, 0, in.length);
344:
345: if (mc.getPrecision() != 0)
346: {
347: BigDecimal temp = this.round(mc);
348: this.intVal = temp.intVal;
349: this.scale = temp.scale;
350: this.precision = temp.precision;
351: }
352: }
353:
354:
362: public BigDecimal(char[] in)
363: {
364: this(in, 0, in.length);
365: }
366:
367:
377: public BigDecimal(char[] in, int offset, int len)
378: {
379:
380: int start = offset;
381:
382: int end = offset + len;
383:
384:
385: int point = offset;
386:
387:
388: int dot = -1;
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416: boolean negative = false;
417: if (in[offset] == '+')
418: {
419: ++start;
420: ++point;
421: }
422: else if (in[offset] == '-')
423: {
424: ++start;
425: ++point;
426: negative = true;
427: }
428:
429:
430:
431: while (point < end)
432: {
433: char c = in[point];
434: if (c == '.')
435: {
436:
437: if (dot != -1)
438: throw new NumberFormatException("multiple `.'s in number");
439: dot = point;
440: }
441:
442: else if (c == 'e' || c == 'E')
443: break;
444:
445:
446: else if (!Character.isDigit(c))
447: throw new NumberFormatException("unrecognized character at " + point
448: + ": " + c);
449: ++point;
450: }
451:
452:
453:
454: StringBuilder val = new StringBuilder(point - start - 1);
455: if (dot != -1)
456: {
457:
458:
459: val.append(in, start, dot - start);
460: val.append(in, dot + 1, point - dot - 1);
461: scale = point - 1 - dot;
462: }
463: else
464: {
465:
466:
467: val.append(in, start, point - start);
468: scale = 0;
469: }
470: if (val.length() == 0)
471: throw new NumberFormatException("no digits seen");
472:
473:
474: if (negative)
475: val.insert(0, '-');
476: intVal = new BigInteger(val.toString());
477:
478:
479:
480:
481: if (point < end)
482: {
483: point++;
484:
485: if (in[point] == '+')
486: point++;
487:
488:
489:
490: if (point >= end)
491: throw new NumberFormatException("no exponent following e or E");
492:
493: try
494: {
495:
496:
497:
498: scale -= Integer.parseInt(new String(in, point, end - point));
499: }
500: catch (NumberFormatException ex)
501: {
502: throw new NumberFormatException("malformed exponent");
503: }
504: }
505: }
506:
507: public BigDecimal (String num) throws NumberFormatException
508: {
509: int len = num.length();
510: int start = 0, point = 0;
511: int dot = -1;
512: boolean negative = false;
513: if (num.charAt(0) == '+')
514: {
515: ++start;
516: ++point;
517: }
518: else if (num.charAt(0) == '-')
519: {
520: ++start;
521: ++point;
522: negative = true;
523: }
524:
525: while (point < len)
526: {
527: char c = num.charAt (point);
528: if (c == '.')
529: {
530: if (dot >= 0)
531: throw new NumberFormatException ("multiple `.'s in number");
532: dot = point;
533: }
534: else if (c == 'e' || c == 'E')
535: break;
536: else if (Character.digit (c, 10) < 0)
537: throw new NumberFormatException ("unrecognized character: " + c);
538: ++point;
539: }
540:
541: String val;
542: if (dot >= 0)
543: {
544: val = num.substring (start, dot) + num.substring (dot + 1, point);
545: scale = point - 1 - dot;
546: }
547: else
548: {
549: val = num.substring (start, point);
550: scale = 0;
551: }
552: if (val.length () == 0)
553: throw new NumberFormatException ("no digits seen");
554:
555: if (negative)
556: val = "-" + val;
557: intVal = new BigInteger (val);
558:
559:
560: if (point < len)
561: {
562: point++;
563: if (num.charAt(point) == '+')
564: point++;
565:
566: if (point >= len )
567: throw new NumberFormatException ("no exponent following e or E");
568:
569: try
570: {
571: scale -= Integer.parseInt (num.substring (point));
572: }
573: catch (NumberFormatException ex)
574: {
575: throw new NumberFormatException ("malformed exponent");
576: }
577: }
578: }
579:
580: public static BigDecimal valueOf (long val)
581: {
582: return valueOf (val, 0);
583: }
584:
585: public static BigDecimal valueOf (long val, int scale)
586: throws NumberFormatException
587: {
588: if ((scale == 0) && ((int)val == val))
589: switch ((int) val)
590: {
591: case 0:
592: return ZERO;
593: case 1:
594: return ONE;
595: }
596:
597: return new BigDecimal (BigInteger.valueOf (val), scale);
598: }
599:
600: public BigDecimal add (BigDecimal val)
601: {
602:
603:
604:
605: BigInteger op1 = intVal;
606: BigInteger op2 = val.intVal;
607: if (scale < val.scale)
608: op1 = op1.multiply (BigInteger.TEN.pow (val.scale - scale));
609: else if (scale > val.scale)
610: op2 = op2.multiply (BigInteger.TEN.pow (scale - val.scale));
611:
612: return new BigDecimal (op1.add (op2), Math.max (scale, val.scale));
613: }
614:
615:
625: public BigDecimal add (BigDecimal val, MathContext mc)
626: {
627: return add(val).round(mc);
628: }
629:
630: public BigDecimal subtract (BigDecimal val)
631: {
632: return this.add(val.negate());
633: }
634:
635:
645: public BigDecimal subtract (BigDecimal val, MathContext mc)
646: {
647: return subtract(val).round(mc);
648: }
649:
650: public BigDecimal multiply (BigDecimal val)
651: {
652: return new BigDecimal (intVal.multiply (val.intVal), scale + val.scale);
653: }
654:
655:
665: public BigDecimal multiply (BigDecimal val, MathContext mc)
666: {
667: return multiply(val).round(mc);
668: }
669:
670: public BigDecimal divide (BigDecimal val, int roundingMode)
671: throws ArithmeticException, IllegalArgumentException
672: {
673: return divide (val, scale, roundingMode);
674: }
675:
676: public BigDecimal divide(BigDecimal val, int newScale, int roundingMode)
677: throws ArithmeticException, IllegalArgumentException
678: {
679: if (roundingMode < 0 || roundingMode > 7)
680: throw
681: new IllegalArgumentException("illegal rounding mode: " + roundingMode);
682:
683: if (intVal.signum () == 0)
684: return newScale == 0 ? ZERO : new BigDecimal (ZERO.intVal, newScale);
685:
686:
687: BigInteger valIntVal = val.intVal;
688: int power = newScale - (scale - val.scale);
689: if (power < 0)
690: {
691:
692:
693: valIntVal = valIntVal.multiply (BigInteger.TEN.pow (-power));
694: power = 0;
695: }
696:
697: BigInteger dividend = intVal.multiply (BigInteger.TEN.pow (power));
698:
699: BigInteger parts[] = dividend.divideAndRemainder (valIntVal);
700:
701: BigInteger unrounded = parts[0];
702: if (parts[1].signum () == 0)
703: return new BigDecimal (unrounded, newScale);
704:
705: if (roundingMode == ROUND_UNNECESSARY)
706: throw new ArithmeticException ("Rounding necessary");
707:
708: int sign = intVal.signum () * valIntVal.signum ();
709:
710: if (roundingMode == ROUND_CEILING)
711: roundingMode = (sign > 0) ? ROUND_UP : ROUND_DOWN;
712: else if (roundingMode == ROUND_FLOOR)
713: roundingMode = (sign < 0) ? ROUND_UP : ROUND_DOWN;
714: else
715: {
716:
717:
718:
719: BigInteger posRemainder
720: = parts[1].signum () < 0 ? parts[1].negate() : parts[1];
721: valIntVal = valIntVal.signum () < 0 ? valIntVal.negate () : valIntVal;
722: int half = posRemainder.shiftLeft(1).compareTo(valIntVal);
723:
724: switch(roundingMode)
725: {
726: case ROUND_HALF_UP:
727: roundingMode = (half < 0) ? ROUND_DOWN : ROUND_UP;
728: break;
729: case ROUND_HALF_DOWN:
730: roundingMode = (half > 0) ? ROUND_UP : ROUND_DOWN;
731: break;
732: case ROUND_HALF_EVEN:
733: if (half < 0)
734: roundingMode = ROUND_DOWN;
735: else if (half > 0)
736: roundingMode = ROUND_UP;
737: else if (unrounded.testBit(0))
738: roundingMode = ROUND_UP;
739: else
740: roundingMode = ROUND_DOWN;
741: break;
742: }
743: }
744:
745: if (roundingMode == ROUND_UP)
746: unrounded = unrounded.add (BigInteger.valueOf (sign > 0 ? 1 : -1));
747:
748:
749: return new BigDecimal (unrounded, newScale);
750: }
751:
752:
759: public BigDecimal divide(BigDecimal divisor)
760: throws ArithmeticException, IllegalArgumentException
761: {
762: return divide(divisor, scale, ROUND_UNNECESSARY);
763: }
764:
765:
774: public BigDecimal remainder(BigDecimal val)
775: {
776: return subtract(divideToIntegralValue(val).multiply(val));
777: }
778:
779:
788: public BigDecimal[] divideAndRemainder(BigDecimal val)
789: {
790: BigDecimal[] result = new BigDecimal[2];
791: result[0] = divideToIntegralValue(val);
792: result[1] = subtract(result[0].multiply(val));
793: return result;
794: }
795:
796:
804: public BigDecimal divideToIntegralValue(BigDecimal val)
805: {
806: return divide(val, ROUND_DOWN).floor().setScale(scale - val.scale, ROUND_DOWN);
807: }
808:
809:
816: private BigDecimal floor()
817: {
818: if (scale <= 0)
819: return this;
820: String intValStr = intVal.toString();
821: intValStr = intValStr.substring(0, intValStr.length() - scale);
822: intVal = new BigInteger(intValStr).multiply(BigInteger.TEN.pow(scale));
823: return this;
824: }
825:
826: public int compareTo (Object obj)
827: {
828: return compareTo((BigDecimal) obj);
829: }
830:
831: public int compareTo (BigDecimal val)
832: {
833: if (scale == val.scale)
834: return intVal.compareTo (val.intVal);
835:
836: BigInteger thisParts[] =
837: intVal.divideAndRemainder (BigInteger.TEN.pow (scale));
838: BigInteger valParts[] =
839: val.intVal.divideAndRemainder (BigInteger.TEN.pow (val.scale));
840:
841: int compare;
842: if ((compare = thisParts[0].compareTo (valParts[0])) != 0)
843: return compare;
844:
845:
846:
847:
848: if (scale < val.scale)
849: thisParts[1] = thisParts[1].multiply
850: (BigInteger.valueOf (10).pow (val.scale - scale));
851: else if (scale > val.scale)
852: valParts[1] = valParts[1].multiply
853: (BigInteger.valueOf (10).pow (scale - val.scale));
854:
855:
856: return thisParts[1].compareTo (valParts[1]);
857: }
858:
859: public boolean equals (Object o)
860: {
861: return (o instanceof BigDecimal
862: && scale == ((BigDecimal) o).scale
863: && compareTo ((BigDecimal) o) == 0);
864: }
865:
866: public int hashCode()
867: {
868: return intValue() ^ scale;
869: }
870:
871: public BigDecimal max (BigDecimal val)
872: {
873: switch (compareTo (val))
874: {
875: case 1:
876: return this;
877: default:
878: return val;
879: }
880: }
881:
882: public BigDecimal min (BigDecimal val)
883: {
884: switch (compareTo (val))
885: {
886: case -1:
887: return this;
888: default:
889: return val;
890: }
891: }
892:
893: public BigDecimal movePointLeft (int n)
894: {
895: return (n < 0) ? movePointRight (-n) : new BigDecimal (intVal, scale + n);
896: }
897:
898: public BigDecimal movePointRight (int n)
899: {
900: if (n < 0)
901: return movePointLeft (-n);
902:
903: if (scale >= n)
904: return new BigDecimal (intVal, scale - n);
905:
906: return new BigDecimal (intVal.multiply
907: (BigInteger.TEN.pow (n - scale)), 0);
908: }
909:
910: public int signum ()
911: {
912: return intVal.signum ();
913: }
914:
915: public int scale ()
916: {
917: return scale;
918: }
919:
920: public BigInteger unscaledValue()
921: {
922: return intVal;
923: }
924:
925: public BigDecimal abs ()
926: {
927: return new BigDecimal (intVal.abs (), scale);
928: }
929:
930: public BigDecimal negate ()
931: {
932: return new BigDecimal (intVal.negate (), scale);
933: }
934:
935:
944: public BigDecimal negate(MathContext mc)
945: {
946: BigDecimal result = negate();
947: if (mc.getPrecision() != 0)
948: result = result.round(mc);
949: return result;
950: }
951:
952:
958: public BigDecimal plus()
959: {
960: return this;
961: }
962:
963:
972: public BigDecimal plus(MathContext mc)
973: {
974: return round(mc);
975: }
976:
977:
983: public BigDecimal round(MathContext mc)
984: {
985: int mcPrecision = mc.getPrecision();
986: int numToChop = precision() - mcPrecision;
987:
988:
989:
990: if (mcPrecision == 0 || numToChop <= 0)
991: return this;
992:
993:
994:
995: BigDecimal div = new BigDecimal(BigInteger.TEN.pow(numToChop));
996: BigDecimal rounded = divide(div, scale, 4);
997: rounded.scale -= numToChop;
998: rounded.precision = mcPrecision;
999: return rounded;
1000: }
1001:
1002:
1008: public int precision()
1009: {
1010: if (precision == 0)
1011: {
1012: String s = intVal.toString();
1013: precision = s.length() - (( s.charAt(0) == '-' ) ? 1 : 0);
1014: }
1015: return precision;
1016: }
1017:
1018:
1036: public String toString()
1037: {
1038:
1039:
1040: String bigStr = intVal.toString();
1041: if (scale == 0)
1042: return bigStr;
1043:
1044: boolean negative = (bigStr.charAt(0) == '-');
1045: int point = bigStr.length() - scale - (negative ? 1 : 0);
1046:
1047: StringBuilder val = new StringBuilder();
1048:
1049: if (scale >= 0 && (point - 1) >= -6)
1050: {
1051:
1052: if (point <= 0)
1053: {
1054:
1055: if (negative)
1056: val.append('-');
1057:
1058: val.append('0').append('.');
1059: while (point < 0)
1060: {
1061: val.append('0');
1062: point++;
1063: }
1064:
1065: val.append(bigStr.substring(negative ? 1 : 0));
1066: }
1067: else
1068: {
1069:
1070:
1071: val.append(bigStr);
1072: val.insert(point + (negative ? 1 : 0), '.');
1073: }
1074: }
1075: else
1076: {
1077:
1078: val.append(bigStr);
1079:
1080:
1081: if (bigStr.length() > 1)
1082: val.insert( ( negative ? 2 : 1 ), '.');
1083:
1084: val.append('E');
1085: if (point - 1 >= 0)
1086: val.append('+');
1087: val.append( point - 1 );
1088: }
1089: return val.toString();
1090: }
1091:
1092:
1101: public String toEngineeringString()
1102: {
1103:
1104:
1105: String bigStr = intVal.toString();
1106: if (scale == 0)
1107: return bigStr;
1108:
1109: boolean negative = (bigStr.charAt(0) == '-');
1110: int point = bigStr.length() - scale - (negative ? 1 : 0);
1111:
1112:
1113: int adjExp = point - 1;
1114: StringBuilder val = new StringBuilder();
1115:
1116: if (scale >= 0 && adjExp >= -6)
1117: {
1118:
1119: if (point <= 0)
1120: {
1121:
1122: if (negative)
1123: val.append('-');
1124:
1125: val.append('0').append('.');
1126: while (point < 0)
1127: {
1128: val.append('0');
1129: point++;
1130: }
1131:
1132: val.append(bigStr.substring(negative ? 1 : 0));
1133: }
1134: else
1135: {
1136:
1137:
1138: val.append(bigStr);
1139: val.insert(point + (negative ? 1 : 0), '.');
1140: }
1141: }
1142: else
1143: {
1144:
1145:
1146:
1147: val.append(bigStr);
1148: int zeros = adjExp % 3;
1149: int dot = 1;
1150: if (adjExp > 0)
1151: {
1152:
1153:
1154: dot += zeros;
1155: adjExp -= zeros;
1156: }
1157: else
1158: {
1159:
1160:
1161:
1162:
1163:
1164:
1165: if (zeros == -2)
1166: {
1167: dot += 1;
1168: adjExp -= 1;
1169: }
1170: else if (zeros == -1)
1171: {
1172: dot += 2;
1173: adjExp -= 2;
1174: }
1175: }
1176:
1177:
1178:
1179: if (dot > val.length())
1180: {
1181: while (dot > val.length())
1182: val.append('0');
1183: }
1184: else if (bigStr.length() > dot)
1185: val.insert(dot + (negative ? 1 : 0), '.');
1186:
1187:
1188: val.append('E');
1189: if (adjExp >= 0)
1190: val.append('+');
1191: val.append(adjExp);
1192: }
1193: return val.toString();
1194: }
1195:
1196:
1206: public String toPlainString()
1207: {
1208:
1209:
1210: String bigStr = intVal.toString();
1211: if (scale == 0)
1212: return bigStr;
1213:
1214:
1215: boolean negative = (bigStr.charAt(0) == '-');
1216:
1217: int point = bigStr.length() - scale - (negative ? 1 : 0);
1218:
1219: StringBuffer sb = new StringBuffer(bigStr.length() + 2
1220: + (point <= 0 ? (-point + 1) : 0));
1221: if (point <= 0)
1222: {
1223:
1224: if (negative)
1225: sb.append('-');
1226: sb.append('0').append('.');
1227: while (point < 0)
1228: {
1229: sb.append('0');
1230: point++;
1231: }
1232: sb.append(bigStr.substring(negative ? 1 : 0));
1233: }
1234: else if (point < bigStr.length())
1235: {
1236:
1237:
1238: sb.append(bigStr);
1239: sb.insert(point + (negative ? 1 : 0), '.');
1240: }
1241: else
1242: {
1243:
1244: sb.append(bigStr);
1245: for (int i = bigStr.length(); i < point; i++)
1246: sb.append('0');
1247: }
1248: return sb.toString();
1249: }
1250:
1251:
1256: public BigInteger toBigInteger ()
1257: {
1258:
1259:
1260: if (scale > 0)
1261: return intVal.divide (BigInteger.TEN.pow (scale));
1262: else if (scale < 0)
1263: return intVal.multiply(BigInteger.TEN.pow(-scale));
1264: return intVal;
1265: }
1266:
1267:
1273: public BigInteger toBigIntegerExact()
1274: {
1275: if (scale > 0)
1276: {
1277:
1278: BigInteger[] result =
1279: intVal.divideAndRemainder(BigInteger.TEN.pow(scale));
1280: if (result[1].equals(BigInteger.ZERO))
1281: return result[0];
1282: throw new ArithmeticException("No exact BigInteger representation");
1283: }
1284: else if (scale < 0)
1285:
1286: return intVal.multiply(BigInteger.TEN.pow(-scale));
1287:
1288: return intVal;
1289: }
1290:
1291: public int intValue ()
1292: {
1293: return toBigInteger ().intValue ();
1294: }
1295:
1296:
1304: public BigDecimal stripTrailingZeros()
1305: {
1306: String intValStr = intVal.toString();
1307: int newScale = scale;
1308: int pointer = intValStr.length() - 1;
1309:
1310:
1311:
1312: while (intValStr.charAt(pointer) == '0')
1313: {
1314: pointer --;
1315: newScale --;
1316: }
1317:
1318:
1319: BigDecimal result = new BigDecimal(intValStr.substring(0, pointer + 1));
1320: result.scale = newScale;
1321: return result;
1322: }
1323:
1324: public long longValue ()
1325: {
1326: return toBigInteger().longValue();
1327: }
1328:
1329: public float floatValue()
1330: {
1331: return Float.valueOf(toString()).floatValue();
1332: }
1333:
1334: public double doubleValue()
1335: {
1336: return Double.valueOf(toString()).doubleValue();
1337: }
1338:
1339: public BigDecimal setScale (int scale) throws ArithmeticException
1340: {
1341: return setScale (scale, ROUND_UNNECESSARY);
1342: }
1343:
1344: public BigDecimal setScale (int scale, int roundingMode)
1345: throws ArithmeticException, IllegalArgumentException
1346: {
1347:
1348:
1349:
1350: if( scale < 0 ) throw new ArithmeticException("Scale parameter < 0.");
1351: return divide (ONE, scale, roundingMode);
1352: }
1353:
1354:
1363: public static BigDecimal valueOf(double val)
1364: {
1365: if (Double.isInfinite(val) || Double.isNaN(val))
1366: throw new NumberFormatException("argument cannot be NaN or infinite.");
1367: return new BigDecimal(Double.toString(val));
1368: }
1369:
1370:
1377: public BigDecimal scaleByPowerOfTen(int n)
1378: {
1379: BigDecimal result = new BigDecimal(intVal, scale - n);
1380: result.precision = precision;
1381: return result;
1382: }
1383:
1384:
1391: public BigDecimal pow(int n)
1392: {
1393: if (n < 0 || n > 999999999)
1394: throw new ArithmeticException("n must be between 0 and 999999999");
1395: BigDecimal result = new BigDecimal(intVal.pow(n), scale * n);
1396: return result;
1397: }
1398:
1399:
1409: public BigDecimal pow(int n, MathContext mc)
1410: {
1411:
1412:
1413: return pow(n).round(mc);
1414: }
1415:
1416:
1422: public BigDecimal abs(MathContext mc)
1423: {
1424: BigDecimal result = abs();
1425: result = result.round(mc);
1426: return result;
1427: }
1428:
1429:
1435: public BigDecimal ulp()
1436: {
1437: return new BigDecimal(BigInteger.ONE, scale);
1438: }
1439:
1440:
1446: public long longValueExact()
1447: {
1448:
1449: BigDecimal temp = setScale(0, ROUND_UNNECESSARY);
1450: BigInteger tempVal = temp.intVal;
1451:
1452: long result = intVal.longValue();
1453: if (tempVal.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 1
1454: || (result < 0 && signum() == 1) || (result > 0 && signum() == -1))
1455: throw new ArithmeticException("this BigDecimal is too " +
1456: "large to fit into the return type");
1457:
1458: return intVal.longValue();
1459: }
1460:
1461:
1470: public int intValueExact()
1471: {
1472: long temp = longValueExact();
1473: int result = (int)temp;
1474: if (result != temp)
1475: throw new ArithmeticException ("this BigDecimal cannot fit into an int");
1476: return result;
1477: }
1478:
1479:
1488: public byte byteValueExact()
1489: {
1490: long temp = longValueExact();
1491: byte result = (byte)temp;
1492: if (result != temp)
1493: throw new ArithmeticException ("this BigDecimal cannot fit into a byte");
1494: return result;
1495: }
1496:
1497:
1506: public short shortValueExact()
1507: {
1508: long temp = longValueExact();
1509: short result = (short)temp;
1510: if (result != temp)
1511: throw new ArithmeticException ("this BigDecimal cannot fit into a short");
1512: return result;
1513: }
1514: }