Java高级编程

数字操作类

2019-07-24  本文已影响25人  江湖非良人

  程序就是一个数学的处理过程,在Java中提供了相应的数字处理的类库支持

Math

  Math类的主要功能是进行数学计算的操作类,提供有基础的计算公式,这个类的构造方法被私有化了,而且该类的方法提供的方法都是static型方法,即:这些方法都可以通过类名称直接调用。

public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        System.out.println(Math.abs(-10.1));//获取绝对值:10.1
        System.out.println(Math.max(10.2,20.3));//获取最大值:20.3
        System.out.println(Math.log(100));//获取对数:4.605170185988092
        System.out.println(Math.round(15.1));//四舍五入:15
        System.out.println(Math.round(-15.5));//四舍五入:-15
        System.out.println(Math.round(-15.51));//四舍五入:-16
        System.out.println(Math.pow(2.0,3));//幂,2.0的三次幂:8.0
    }
}

  虽然在Math类里面提供有四舍五入的处理方法,但是这个四舍五入在进行处理时,直接将小数点后的所有位进行进位处理,这个肯定不太合适,我们可以实现一个指定位数保留的方法。
范例:自定义的四舍五入功能

class MathUtil {
    private MathUtil() {
    }
    /**
     * 实现数据的四舍五入操作
     * @param num   要进行四舍五入操作的是数字
     * @param scale 四舍五入保留的小数位数
     * @return 四舍五入处理后的结果
     */
    public static double round(double num, int scale) {
        return Math.round(num * Math.pow(10, scale)) / Math.pow(10, scale);
    }
}
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        System.out.println(MathUtil.round(19.855,2));
    }
}

Random

  java.util.Random类的主要功能是产生随机数,这个类主要依靠内部提供方法来完成:

public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        Random random=new Random();
        for (int i = 0; i < 10; i++) {
            System.out.print(random.nextInt(10)+"、");//6、2、2、0、5、7、3、1、9、5、
        }
    }
}

范例:利用Random生成36选7彩票(不包含0,数字不能重复)

public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        int data[] = new int[7];//开辟7个大小的空间
        Random random = new Random();
        int foot = 0;//操作data脚标
        while (foot < 7) {//选择7个数字
            int num = random.nextInt(37);//生成一个小于37的自然数
            if (isUse(num, data)) {//判断是否可用
                data[foot++] = num;//保存数据
            }
        }
        Arrays.sort(data);
        for (int d : data) {
            System.out.print(d + "、");
        }
    }
    /**
     * 判断传入的数字是否为0以及是否在数组中已存在
     *
     * @param num  要判断的数字
     * @param temp 已存在的数据
     * @return 如果该数字不是0并且在数字中不存在返回true, 否则返回false
     */
    public static boolean isUse(int num, int[] temp) {
        if (num == 0) {
            return false;
        }
        for (int t : temp) {
            if (t == num) {
                return false;
            }
        }
        return true;
    }
}

案例一:利用Random类产生5个1~30之间(包括1和30)的随机整数。

public class JavaApiDemo {
    public static void main(String[] args) throws Exception{
        int count=5;//数字个数
        int min=1,max=30;//最小取值1,最大取值为30
        //而我们知道Random.nextInt(n)取值范围是[0,n),则需要在范围[0,n+1-min)取值后加上最小值
        int[] data=new int[count];
        Random random=new Random();
        for (int i=0;i<count;i++){
            data[i]=min+random.nextInt(max+1-min);
        }
        System.out.println("生成结果为:"+Arrays.toString(data));//生成结果为:[28, 3, 24, 4, 20]
    }
}

BigInteger类与BigDecimal

  在进行数学计算的过程中,还有一个大数字的操作类,可以实现海量数字的计算(能提供的也只是基础计算),现在假设一个数字很大,超过了double的范围,那么这时没有任何一种数据类型可以保存下此类的内容,最早的时候只能通过String保存。

String strA="120";
String strB="230";

  如果现在想要进行加法计算,那么就需要逐位拆分,每一个自己计算,然后自己独立控制进位处理,那么这样的开发难度是非常高的,所以为了解决这类问题,提供有两个大数字的操作类:BigInteger、BigDecimal。


大数字类

  之前分析了,当数字很大时只能利用字符串描述数字操作,所有可以观察一下这两个大数字操作类的构造方法:

public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        BigInteger bigA=new BigInteger("242343242342424234234");
        BigInteger bigB=new BigInteger("123231312");
        System.out.println("加法操作:"+bigA.add(bigB));
        System.out.println("减法操作:"+bigA.subtract(bigB));
        System.out.println("乘法操作:"+bigA.multiply(bigB));
        System.out.println("除法操作:"+bigA.divide(bigB));
    }
}

  需要注意的是,虽然提供有大数字操作类,但是整体操作之中还是需要考虑到性能问题。
范例:观察性能问题

public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        BigInteger bigA=new BigInteger("242343242342424234234");
        System.out.println(bigA.pow(Integer.MAX_VALUE));
    }
}

  此时的计算过程是非常漫长的,所以要记住电脑是有极限的。
  既然在进行数学除法计算有可能无法进行整除处理,那么就可以使用其他的除法计算方法来求出余数:

public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        BigInteger bigA = new BigInteger("242343242342424234234");
        BigInteger bigB = new BigInteger("3123213");
        BigInteger[] res = bigA.divideAndRemainder(bigB);
        System.out.println("商:" + res[0] + "、余数:" + res[1]);//商:77594209022062、余数:2909028
    }
}

  如果在开发中计算时,该计算没有超过基本数据类型所包含的位数时,强烈不建议使用大数字类,因为这种计算性能很差。
  BigDecimal操作形式和BigInteger是非常类似的,都有基础的数学支持。
范例:使用BigDecimal计算

public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        BigDecimal bigA = new BigDecimal("242343242342424234234.1");
        BigDecimal bigB = new BigDecimal("3123213.1");
        BigDecimal[] res = bigA.divideAndRemainder(bigB);
        System.out.println("商:" + res[0] + "、余数:" + res[1]);//商:77594206537627、余数:1944920.4
    }
}

但是在使用BigDecimal的时候有一个数据进位的问题,在这个类中定义有如下的除法计算:

class MathUtil {
    private MathUtil() {}
    /**
     * 实现数据的四舍五入操作
     *
     * @param num   要进行四舍五入操作的是数字
     * @param scale 四舍五入保留的小数位数
     * @return 四舍五入处理后的结果
     */
    public static double round(double num, int scale) {
        return new BigDecimal(num).divide(new BigDecimal(1.0), scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
}
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        System.out.println(MathUtil.round(19.8550, 2));
    }
}

  Math的处理由于使用的都是基本数据类型,所以性能一定要高于大数字处理类。

上一篇下一篇

猜你喜欢

热点阅读