13
13
14
14
package com .ibm .as400 .access ;
15
15
16
- import java .lang .reflect .Constructor ;
17
- import java .lang .reflect .InvocationTargetException ;
18
16
import java .math .BigDecimal ;
19
17
import java .math .BigInteger ;
18
+ import java .math .MathContext ;
19
+ import java .math .RoundingMode ;
20
+
20
21
//@DFA new class
21
22
/**
22
23
* The AS400DecFloat class provides a converter between a BigDecimal object and a DecimalFloat type.
@@ -615,7 +616,7 @@ else if ((combination == 0x1eL) && ( sign == -1))
615
616
616
617
617
618
BigInteger bigInt = new java .math .BigInteger (sign , magnitude );
618
- return getNewBigDecimal (bigInt , -exponent );
619
+ return new BigDecimal (bigInt , -exponent );
619
620
620
621
}else
621
622
{
@@ -705,7 +706,7 @@ else if ((combination == 0x1eL) && ( sign == -1))
705
706
706
707
707
708
java .math .BigInteger bigInt = new java .math .BigInteger (sign , magnitude );
708
- return getNewBigDecimal (bigInt , -exponent );
709
+ return new BigDecimal (bigInt , -exponent );
709
710
}
710
711
}
711
712
@@ -853,103 +854,6 @@ private static final int decFloatBitsToDigits (int bits)
853
854
return decimal ;
854
855
}
855
856
856
- /**
857
- * This method rounds the number (unscaled integer value and exponent).
858
- * mcPrecision and mcRoundingMode are what is in jdk 5.0 MathContext.
859
- * What is returned from this method should be the same as what jre 5.0 would
860
- * have rounded to using MathContext and BigDecimal.
861
- */
862
- private static BigDecimal roundByModePreJDK5 (BigInteger intVal , int scale , int mcPrecision , String mcRoundingMode )
863
- {
864
-
865
- BigInteger roundingMax = null ;
866
- if (mcPrecision == 16 )
867
- roundingMax = new BigInteger ("10000000000000000" ); // 16 0s
868
- else
869
- roundingMax = new BigInteger ("10000000000000000000000000000000000" ); // 34 0s
870
-
871
- BigInteger roundingMin = roundingMax .negate ();
872
-
873
- if (roundingMax != null && intVal .compareTo (roundingMax ) < 0
874
- && intVal .compareTo (roundingMin ) > 0 )
875
- return getNewBigDecimal (intVal , scale ); //rounding not needed
876
- //get precision from intVal without 0's on right side
877
- int [] values = SQLDataFactory .getPrecisionForTruncation (getNewBigDecimal (intVal , scale ), mcPrecision ); //=precisionStr.length() - trimCount; //@rnd1
878
- int precisionNormalized = values [0 ]; //@rnd1
879
- int droppedZeros = values [1 ]; //@rnd1 decrease scale by number of zeros removed from precision //@rnd1
880
- if (droppedZeros != 0 ) //@rnd1
881
- { //@rnd1
882
- //adjust intVal number of zeros removed off end //@rnd1
883
- intVal = intVal .divide ( new BigInteger ("10" ).pow (droppedZeros )); //@rnd1
884
- } //@rnd1
885
-
886
- //get number of digits to round off
887
- int drop = precisionNormalized - mcPrecision ;
888
- //@rnd1 if (drop <= 0)
889
- //@rnd1 return getNewBigDecimal(intVal, scale);
890
- BigDecimal rounded = roundOffDigits (intVal , scale , mcRoundingMode , drop );
891
-
892
- if (droppedZeros != 0 ) //@rnd1
893
- { //@rnd1
894
- //adjust rounded bigdecimal by dropped zero count //@rnd1
895
- rounded = rounded .movePointRight (droppedZeros ); //@rnd1
896
- } //@rnd1
897
-
898
- return rounded ; //@rnd1
899
- }
900
-
901
- /**
902
- * Helper method to round off digits
903
- */
904
- private static BigDecimal roundOffDigits (BigInteger intVal , int scale ,
905
- String mcRoundingMode , int dropCount )
906
- {
907
-
908
- BigDecimal divisor = new BigDecimal ((new BigInteger ("10" )).pow (dropCount ), 0 );
909
- BigDecimal preRoundedBD = getNewBigDecimal (intVal , scale );
910
- int roundingMode = 0 ;
911
- try
912
- {
913
- //get int value for RoundingMode from BigDecimal
914
- roundingMode = ((Integer ) Class .forName ("java.math.BigDecimal" ).getDeclaredField (mcRoundingMode ).get (null )).intValue ();
915
- } catch (Exception e )
916
- {
917
- throw new InternalErrorException (InternalErrorException .UNKNOWN , e ); //should never happen
918
- }
919
- BigDecimal rounded = preRoundedBD .divide (divisor , scale , roundingMode ); // do actual rounding here
920
-
921
- BigInteger bigIntPart = rounded .unscaledValue ();
922
-
923
- rounded = getNewBigDecimal (bigIntPart , scale - dropCount );
924
-
925
- return rounded ;
926
- }
927
-
928
- /**
929
- Creates and returns a new BigDecimal based on parameters.
930
- This is a temporary hack due to pre-jre 1.5 not being able to handle negative scales (positive exp)
931
- After we no longer support pre-java 1.5, this method can be replaced with new BigDecimal(bigInt, scale).
932
- @param bigInt BigInteger part.
933
- @param scale scale part.
934
- **/
935
- private static BigDecimal getNewBigDecimal (BigInteger bigInt , int scale )
936
- {
937
- BigDecimal bigDecimal = null ;
938
- try {
939
- bigDecimal = new BigDecimal (bigInt , scale );
940
- }catch (NumberFormatException e )
941
- {
942
- //note that creating BigDecimal with negative scale is ok in 5, but not in 1.4
943
- //deal with negative scale in pre jdk 5.0 here
944
- if (scale > 0 )
945
- throw e ;
946
- bigDecimal = new BigDecimal (bigInt );
947
- bigDecimal = bigDecimal .movePointRight (-scale );
948
- }
949
-
950
- return bigDecimal ;
951
- }
952
-
953
857
//Decimal float. //@DFA
954
858
/**
955
859
Rounds the precision of a BigDecimal by removing least significant digits from
@@ -959,54 +863,10 @@ private static BigDecimal getNewBigDecimal(BigInteger bigInt, int scale)
959
863
@param roundingMode to use when truncating
960
864
* @return the rounded BigDecimal
961
865
**/
962
- public static BigDecimal roundByMode (BigDecimal bd , int precision , String roundingMode )
963
- {
964
- BigDecimal roundedBD = null ;
965
-
966
- //MathContext is in jdk1.5. So use reflection so code will build under pre-1.5
967
- //later, use this when we move to jdk1.5
968
- //All we are doing below is: bdAbs = inValue.abs(new MathContext(16, roundingMode));
969
- boolean isGEJVM50 = true ;
970
- try
971
- {
972
- //in this try block, we do rounding via BigDecimal and MathContext
973
- Class cls = Class .forName ("java.math.MathContext" ); //thorw ClassNotFoundException if pre 1.5 jvm
974
- Constructor ct = cls .getConstructor (new Class [] { Integer .TYPE , Class .forName ("java.math.RoundingMode" ) });
975
- Object arglist [] = new Object [2 ];
976
- arglist [0 ] = Integer .valueOf (precision ); //MathContext.DECIMAL64 (16 or 34 char decfloat precision)
977
- arglist [1 ] = Class .forName ("java.math.RoundingMode" ).getDeclaredField (roundingMode .substring (6 )).get (null ); //@pdc remove "ROUND_"
978
-
979
- Object mathContextRounded = ct .newInstance (arglist ); //ie. new MathContext(16or34, RoundingMode.x);
980
- Object [] arglist2 = new Object []{mathContextRounded };
981
- Class [] c = new Class [] { Class .forName ("java.math.MathContext" ) };
982
- java .lang .reflect .Method method = java .math .BigDecimal .class .getDeclaredMethod ("round" , c );
983
-
984
- roundedBD = (java .math .BigDecimal ) method .invoke (bd , arglist2 );
985
- }
986
- //Unfortunately, we cannot just catch Exception since we do not want to miss any real exceptions
987
- //from rounding etc. And can't re-throw Exception it since method is not declared with "throws"
988
- catch (ClassNotFoundException e )
989
- {
990
- //got exception due to pre-java 5.0.
991
- isGEJVM50 = false ;
992
- }
993
- catch (NoSuchMethodException e )
994
- { isGEJVM50 = false ; }
995
- catch (NoSuchFieldException e )
996
- { isGEJVM50 = false ; }
997
- catch (IllegalAccessException e )
998
- { isGEJVM50 = false ; }
999
- catch (InvocationTargetException e )
1000
- { isGEJVM50 = false ; }
1001
- catch (InstantiationException e )
1002
- { isGEJVM50 = false ; }
1003
-
1004
- if (isGEJVM50 == false )
1005
- {
1006
- //use our rounding code to round in pre java 5.0
1007
- roundedBD = roundByModePreJDK5 (bd .unscaledValue (), bd .scale (), precision , roundingMode );
1008
- }
1009
-
866
+ public static BigDecimal roundByMode (BigDecimal bd , int precision , RoundingMode roundingMode )
867
+ {
868
+ MathContext mathContext = new MathContext (precision , roundingMode );
869
+ BigDecimal roundedBD = bd .round (mathContext );
1010
870
return roundedBD ;
1011
871
}
1012
872
0 commit comments