BigDecimal的常用方法,求平方差, (no exact representable decimal result)



又是很久没有写blog了,打算上个周末写的,结果感冒躺了两天,用了三包纸。我也是要醉了。今天写下BigDecimal的常用方法,还写了一个求平放差的方法。有用的到的或对你有帮助的请留下你的脚印。哈哈。。。谢谢了。。。。

       Javajava.math包中提供的APIBigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。floatdouble只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimalBigDecimal所创建的是对象,我们不能使用传统的+-*/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法.

BigDecimal的常用方法:

public BigDecimal add(BigDecimal augend)加的方法
public BigDecimal subtract(BigDecimal subtrahend)减的方法
public BigDecimal multiply(BigDecimal multiplicand)乘的方法
public BigDecimal divide(BigDecimal divisor)除

方法返回的也是一个BigDecimal对象,关于BigDecimal怎么转换为基本类型?

在这里大家看看先看看他的一些常用的

Constructor:

public BigDecimal(double val) (public BigDecimal(double val, MathContext mc))
public BigDecimal(int val)
public BigDecimal(long val)
public BigDecimal(String val)

上述每一个Constructor都有两个参数的后面的参数为MathContext。这个构造是

 将 double 转换为 BigDecimal(根据上下文设置进行舍入)。如:BigDecimal big = new BigDecimal(1.23d, MathContext.DECIMAL64);但是他的方法说明里有这样的一句话:

The results of this constructor can be somewhat unpredictable and its use is generally not recommended; see the notes under the {@link #BigDecimal(double)} constructor

这个构造函数可以有些不可预测的结果一般不建议使用。看BigDecimal(double)这个构造函数。

所以我们还是用常规的那个后面不带MathContext的方法吧。

继续:看完构造了,发现他里的api里面提供的转换为基本类型的方法:

public int intValue();将BigDecimal对象转换为int;
public int doubleValue();将BigDecimal对象转换为double;

public int floatValue();将BigDecimal对象转换为float;
public int byteValue();将BigDecimal对象转换为byte;

在这里我们要注意BigDecimal的转换的基本类型的位数。如byteValue()如果一个(-128 - 127)的数则没有问题,但是如果超过了这个范围则会出问题。这里我想有大家都知道这是为神马吧。虽然这个是一个小问题,但是切记在写代码的时候记得注意一下。有时写的飞快就忘了。哈哈。。我就是这样的。转换为基本类型就写到这里。


回到上面我们的四个基本运算方法:值得注意的是我们的

public BigDecimal divide(BigDecimal divisor)

除的方法这里有时会报出一个

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result。

到了这里大家看看divide这个方法的异常:

NullPointerException - if divisor == null. 

ArithmeticException - if divisor == 0. 

ArithmeticException - if the result cannot be represented exactly


也就是说我们传递的参数有可以能为0,这个大家很容易理解。另外一个说的是这个结果不能精准的表示。结果为什么不能精准的表示类?那就是他的结果为无限循环小数。所以我们用这个方法最好用他的另外的放方法:

public BigDecimal divide(BigDecimal divisor, int roundingMode);
如:

BigDecimal.divide(63.56f, BigDecimal.ROUND_HALF_UP)

这样就解决了。关于后面那个参数还有很多我就不多一一细说了。自己看api。

最后在给大家介绍几个方法:

public BigDecimal abs()求绝对值。
public BigDecimal setScale(int newScale, int roundingMode)设置他的精度。
public BigDecimal pow(int n)求幂函数。如:new BigDecimal(2).pow(2)==》4他的答案为4也就是2的2次幂是4;

在这里BigDecimal并没有提供一个开根号的方法。我们就只好借助Math.sqrt方法了。

下面是一个求一组数的平放差方法:

public BigDecimal getQuadraticByList(List xList,int newScale){
		BigDecimal sum = null;
		for (int i = 0; i < xList.size(); i++) {
			if (sum == null) {
				sum = xList.get(i);
			}else{
				sum = sum.add(xList.get(i));
			}	
		}
		BigDecimal sumAvg = sum.divide(new BigDecimal(xList.size()),BigDecimal.ROUND_HALF_DOWN);
		BigDecimal sumQuadratic = null;
		for (int i = 0; i < xList.size(); i++) {
			if (sumQuadratic == null) {
				sumQuadratic = xList.get(i).subtract(sumAvg).pow(2);
			}else{
				sumQuadratic = sumQuadratic.add(xList.get(i).subtract(sumAvg).pow(2));
			}
		}
		sumQuadratic = sumQuadratic.divide(new BigDecimal(xList.size()),BigDecimal.ROUND_HALF_DOWN);
		BigDecimal sumAvgQuadratic = new BigDecimal(Math.sqrt(sumQuadratic.doubleValue()));
		System.out.println(sumAvgQuadratic);
		sumAvgQuadratic = sumAvgQuadratic.setScale(newScale != 0 ? newScale : 20,BigDecimal.ROUND_HALF_DOWN);
		return sumAvgQuadratic;
	}

public BigDecimal getQuadraticByList(List xList,int newScale)第一参数为你要求平方差的数组集合。第二个是精度。
欢迎留下脚印。。。嘎嘎。。。











你可能感兴趣的:(杂记)