Math、BigDecimal、BigInteger的API总结和错误用法

Header

        在代码的过程中,或多或少会用到MAth,BigDecimal,BigInteger等类来进行一些数学运算,但是其中有很多API不常用的话,很容易不太回忆,那么就对这些API总结一下,同时,也会对在使用这些API的过程中,一些出现过的问题也会持续更新的。

目录

 Math

 BigDecimal

 BigInteger


Body

    Math

API 参数 返回值 说明
Math.E double 比任何其他值都更接近e(自然对数的底数)的double值
Math.PI double 比任何其他值都更接近 pi(即圆的周长与直径之比)的 double 值
Math.abs() int | long | float | double int | long | float | double 对各种数据类型求绝对值
Math.cos() double double 求余弦值
Math.sin() double double 求正弦值
Math.tan() double double 求正切值
Math.acos() double double 求反余弦值
Math.asin() double double 求反正弦值
Math.atan() double double 求反正切值
Math.atan2() double(x) & double(y) double 求向量(x,y)与x轴的夹角
Math.cbrt() double double 求立方根
Math.sqrt() double double 求平方根
Math.max()

int & int |

long & long |

float & float |

double & double

int | long | float | double 求两数中的最大值
Math.min()

int & int |

long & long |

float & float |

double & double

int | long | float | double 求两数中的最小值
Math.log() double double 求自然对数(底数为e)
Math.log10() double double 求底数为10的对数
Math.log1p() double(x) double 求x + 1的自然对数
注:对数运算函数只能传double型数据并返回double型数据,不能重载
Math.exp() double(x) double

求e^x的值

Math.expm1() double(x) double 求e^x - 1的值
Math.pow() double (x) & double (y) double 求 x^ y的值
Math.random() double 返回(0.0~1.0)之间的double值
Math.toDegrees() double double 弧度换角度
Math.toRadians() double double 角度换弧度
Math.ceil() double (x) double 返回大于x的第一个整数所对应的浮点数(值是整数,但类型是浮点型)
Math.floor() double (x) double 返回小于x的第一个整数所对应的浮点数(值是整数,但类型是浮点型)
Math.rint() double (x) double 返回最接近x的整数的double

Math、BigDecimal、BigInteger的API总结和错误用法

我们可以看到Math类的构造函数是私有的,因为在面向对象中类是抽象的而对象是具体的,由于数学本身是抽象的没办法具体,所以Math类不能实例化为对象。

    BigDecimal

    先说下BigDecimal的setScale()吧

API 说明
setScale(1) 表示保留一位小数,默认使用四舍五入方式
setScale(1,BigDecimal.ROUND_DOWN)

直接删除多余的小数位,如2.35变为2.3

向零方向舍入的舍入模式

setScale(1,BigDicimal.ROUND_UP)

进位处理,2.35变为2.4

远离零方向舍入的舍入模式

setScale(1,BigDecimal.ROUND_HALF_UP)

四舍五入,2.35变为2.4

向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入

setScale(1,BigDecimal.ROUND_HALF_DOWN)

四舍五入,2.35变为2.3,如果是5则向下舍去

向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入

setScale(1,BigDecimal.ROUND_CEILING) 向正无限大方向舍入的舍入模式
setScale(1,BigDecimal.ROUND_FLOOR) 向负无限大方向舍入的舍入模式
setScale(1,BigDecimal.ROUND_UNNECESSARY) 用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。(默认模式)

(下面注释的这几点摘自https://blog.csdn.net/ahwr24/article/details/7048724

注释:

1:

scale指的是你小数点后的位数。比如123.456则score就是3.
score()就是BigDecimal类中的方法啊。
比如:BigDecimal b = new BigDecimal("123.456");

b.scale(),返回的就是3.

2:
roundingMode是小数的保留模式。它们都是BigDecimal中的常量字段,有很多种。
比如:BigDecimal.ROUND_HALF_UP表示的就是4舍5入。
3:
pubilc BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
的意思是说:我用一个BigDecimal对象除以divisor后的结果,并且要求这个结果保留有scale个小数位,roundingMode表示的就是保留模式是什么,是四舍五入啊还是其它的,你可以自己选!

4:对于一般add、subtract、multiply方法的小数位格式化如下:

BigDecimal mData = new BigDecimal("9.655").setScale(2, BigDecimal.ROUND_HALF_UP);
        System.out.println("mData=" + mData);

----结果:----- mData=9.66

API 参数 返回值 说明
new BigDecimal(double d) double BigDecimal 以double值来创建一个BigDecimal对象
new BigDecimal(String s) String BigDecimal 以String值来创建一个BigDecimal对象

注意:

        1、参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。

        2、另一方面,String 构造方法是完全可预知的:写入 newBigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用String构造方法

        3、当double必须用作BigDecimal的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用Double.toString(double)方法,然后使用BigDecimal(String)构造方法,将double转换为String。要获取该结果,请使用static valueOf(double)方法

add() BigDecimal BigDecimal 加法操作
subtract() BigDecimal BigDecimal 减法操作
multiply() BigDecimal BigDecimal 乘法操作
divide() BigDecimal BigDecimal 除法操作

intValue()

int 输出值的int型
doubleValue() double 输出值的double型
floatValue() float 输出值的float型
longValue() long 输出值的long型

其中,在使用BigDecimal的过程中会碰到很多问题,我这里也遇到过一些问题,但是就不一一敲了,给几个遇到过的问题的链接看看吧。

BigDecimal的double入参的构造函数导致的数据损失精度问题

BigDecimal不可变类型以及除法抛ArithmeticException:Non-terminating decimal expansion问题

    BigInteger

API 参数 返回值 说明
new BigInteger(String s) String BigInteger 将十进制字符串转化为BigInteger
new BigInteger(byte[] b) byte[] BigInteger 具体理解请点击这里
new BigInteger(String s,int radix) String & int BigInteger 将radix进制的字符串转化为BigInteger
new BigInteger(int numBits,Random rnd) int & Random BigInteger 随机生成0到2的numBits次方 - 1的随机数
new BigInteger(int signum,byte[] magnitude) int & byte[] BigInteger signum为符号位,1为正,0为0,-1为负
new BigInteger(int bitLength,int certainty,Random rnd) int & int & Random BigInteger 随机生成一个 长度为bitLength的 可能性大于(1-1/(2的certainty次方))是素数 的数
BigInteger.ZERO BigInteger 0常量
BigInteger.ONE BigInteger 1常量
BigInteger.TEN BigInteger 10常量
BigInteger.valueOf()

long (x)

BigInteger 值等于x的BigInteger
add() BigInteger BigInteger 加法
subtract() BigInteger BigInteger 减法
multiply() BigInteger BigInteger 乘法
divide() BigInteger BigInteger 除法
mod() BigInteger BigInteger a.mod(b) 取模a%b b需大于0 5mod3=2 -5mod3=1
remainder() BigInteger BigInteger a.remainder(b) 求余 5rem3=2 -5rem3=-2 5rem-3=2 
divideAndRemainder() BigInteger BigInteger[] a.divideAndRemainder(b) [0]为a/b [1]为a%b
equals() BigInteger boolean a.equals(b)  a==b?
signum() int a.signum() a的正负 正为1 0为0 负为-1
ads() BigInteger a.abs()   绝对值|a|
compareTo() BigInteger BigInteger a.compareTo(b)  比较a>b返回1 a==b返回0 a<b返回-1
negate() BigInteger a.negate()  相反数-a
max() BigInteger BigInteger a.max(b)     max(a,b)
min() BigInteger BigInteger a.min(b)     min(a,b)
pow() int BigInteger a.pow(3)    a的3次方
...还有不少,不过用的不多      

其实,BigInteger 和BigDecimal有一些类似的地方,比如不可变类型等等

BigInteger不可变类型引发的常见问题

再有新问题再更新吧

End

        由于最近在看算法,会用到很多这三个类的api,而自己去打开类看吧,麻烦,去网上搜,也麻烦,不如自己总结一下,加上遇到的问题,也算是做个笔记,如果有经常用到这些类的api的同志们,希望能帮助到你们。