现在的位置: 首页 > 综合 > 正文

BigDecimal(-)Difference of BigDecimal toString() method between JDK1.4 and above version

2018年03月18日 ⁄ 综合 ⁄ 共 4300字 ⁄ 字号 评论关闭

Difference of BigDecimal toString() method between JDK1.4 and above version
BigDecimal的toString方法在JDK1.4和1.4版本以后中的区别

1 Difference

  BigDecimal.toString() returns decimals in scientific notation since JDK 1.5 .Since JDK 1.5 the behavior of BigDecimal.toString() has changed. It does not only return decimals in n.nnn-like format anymore, it returns now a String like 0-E18. With Java 5.0,
BigDecimal.toString() can return a String in scientific notation. As we use a BigDecimal for the XML schema type <xs:decimal>, this is illegal (as per XML schema specification, this is not allowed).  As a result of this, BigDecimal.toPlainString() should be
used for Java 5.0 and above ( ideally for BigDecimals representing ,xs>decimal> only). It looks like the code in question (within Marshaller) will have to take into account the JVM release number to make an educated decision.

The diffrence can be seen from following picture:

1) jdk1.4 output:

2)jdk 1.7 output:

2 Cofusing of toString method
   When we use toString method, the number sometimes print in scientific notation, but sometimes(e.g. 17) the output is not printed in scientific notation in Java5.0 and above?
Answer:
  It's basically because you don't have enough significant digits. If you multiply something that only has 1 significant digit with 100, then you get something with only 1 significant digit. If it shows "10" then that basically says that it has 2 significant
digits. The way to show it only has 1 significant digit is to show "1 x 10^1".
  The following two decimals have the same value (10), but different "scales" (where they start counting significant digits; the top has 2 sig figs, the bottom has 1):
//---------------------------------------------------------------------
System.out.println(new BigDecimal(BigInteger.TEN, 0));  // prints 10
System.out.println(new BigDecimal(BigInteger.ONE, -1)); // prints 1E+1
//---------------------------------------------------------------------

3 Solution
  If you switch your application from jdk 1.4 to 1.5 you get different results using Castor. Usage of BigDecial.toString() in Marshaller inconsistent when switching from Java 1.4 (and below) to Java 5.0 (and above) .The following
is the solution code:

import java.lang.reflect.Method;
import java.math.BigDecimal;

public class BigDecimalUtil {

    //-----------------------------------------------------------------------------------
    /**
     * number presents not using scientific notation
     * use the java.specification.version property to selectively call either BigDecimal.toString() or BigDecimal.toPlainString().
     * @param bd BigDecimal object
     * @return the number original presentation
     */
    public static String convertBigDecimalToString(BigDecimal bd) {
            String stringValue=null;
            float javaVersion = Float.parseFloat(System.getProperty("java.specification.version"));
            if (javaVersion >= 1.5) {
                // as of Java 5.0 and above, BigDecimal.toPlainString() should be used.
                Method method;
                try {
                    method = java.math.BigDecimal.class.getMethod("toPlainString", (Class[]) null);
                    stringValue = (String) method.invoke(bd, (Object[]) null);
                } catch (Exception e) {
                    System.out.println("Problem accessing java.math.BigDecimal.toPlainString()");
                }
            } else {
                // use BigDecimal.toString() with Java 1.4 and below
                stringValue = bd.toString();
            }
            return stringValue;
        } //end convertBigDecimalToString()
    //-----------------------------------------------------------------------------------
    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("java -version:"+System.getProperty("java.specification.version"));
        
        BigDecimal bd=new BigDecimal("0.000000000000001");
        System.out.println(convertBigDecimalToString(bd));    
    }
    //-----------------------------------------------------------------------------------
}

run the  main method with diffrent jdk version, the output is the same :0.000000000000001

Advise:we
should best usinig the string constructor when new a BigDecimal (like BigDecimal bd=new BigDecimal("0.000000000000001");) if you want to get the original number value.

4 Appendix

4.1 How to Use Java BigDecimal: A Tutorial
url:http://www.opentaps.org/docs/index.php/How_to_Use_Java_BigDecimal:_A_Tutorial

4.2 BigDecimal's toString method in JSE5 API

//Chinese language---------------------------------------------------------------------
url:http://doc.java.sun.com/DocWeb/api/java.math.BigDecimal?lang=zh_cn&mode=Read

//English language---------------------------------------------------------------------
url:http://docs.oracle.com/javase/7/docs/api/

抱歉!评论已关闭.