Java 这玩意好是好但是相对于Python这类动态语言而言有一个要命的问题,那就是类型带来的一些问题,由于Java 算是一个半静态语言,在声明一个变量的时候会在内存根据类型给你开一个内存。那么这样一来问题就来了,如果我的数贼大就相当容易溢出。有些题目说了可以取余还好办,但是如果没说咋办。那就只能考虑大数问题了。这样一来我们需要考虑的问题就太多了。
不过还好在Java里面其实是有专门处理大数问题的API的。核心的实现原理的话其实和咱们的Python解释器实现Python 1+1 是一样的。 这里咱们扯个闲篇,就是在Python解释器里面实现1+1到底有多难。首先Python是作为一个动态语言,最明显的就是你不需要声明你的变量类型。那你写的时候是爽了,那么解释器怎么知道你的变量是啥类型的,我们都知道Python底层呢是C语言或者Java,当然看你用的是哪个解释器,一般使用的是C解释器,所以本质上,Python代码在运行的时候其实是C语言程序在运行,在推断你的Python代码。
我们都知道Java可以被预编译,所以你idea的代码提示相当棒,但是Python不是,他是动态的,所以你发现你的pycharm的代码提示性其实没有idea好。ok,我们来看看这个解释器先干了啥,首先毫无疑问,由于我是C语言程序在执行代码,所以自然我需要去推断一下你的Python代码里面的变量类型,比如你是int类型的,然后我再用C语言程序给你分配空间,问题来了,对于Python用户而言,他只会去关系我这个里面放的是数字,不会关心咱们的变量到底会不会溢出,事实上在高中的时候我就没想过会有溢出问题,直到我遇到了C语言。 所以C语言解释器还需要去判断一下这个类型的值的长度,一旦太长了,那么必然就需要去使用大数方法去处理。例如他会去申请一个数组去存放,在Java的这个API里面也是的。(如下图)然后你看到了Python程序非常的坚强。所以go python 程序员还是不错的,不过这两货的工程性比较难驾驭。Java虽然啰嗦,但是哪怕你是菜鸟你也能写出还能看的代码,但是Python你试试。所以很多人吐槽Python写个几千行就不行了,其实是因为这个工程量变大了,水平比较低的人很难驾驭好。当然代码提示性较差也是一个问题,不过自从 后面 支持了 这样的语法 a:int 之后,情况稍微缓解了一下,不过工程化还是个问题。
OK,闲话少说,该干点事情了。
处理大数整数
BigInteger
这个是自带的而且很老早的版本就有了,所以不用担心蓝桥杯jdk1.7不能用的情况,不过那个增强for的话好像是1.8后的,这个要注意。 这个BIgInteger的使用其实很简单。我们只要注意几点 就是如何使用 BigInteger 进行运算。因为此时咱们不能直接 + - * / 了。
赋值
这里有两个方法
BigInteger a= new BigInteger("1234567890");
BigInteger b = BigInteger.valueOf("123457890)
加减乘除
a.add(b);
a.subtract(b);
a.multiply(b);
a.divide(b)
求幂函,求公约数
a.pow(2)
a.gcd(b) a,b的最大公约数
当然还有a.abs()
比较判断
comareTo()
compareTo()返回一个int型数据:1 大于; 0 等于; -1 小于; max(),min():分别返回大的(小的)那个BigInteger数据;
@Test
public void testCompare() {
BigInteger bigNum1 = new BigInteger("52");
BigInteger bigNum2 = new BigInteger("27");
int num = bigNum1.compareTo(bigNum2);
BigInteger compareMax = bigNum1.max(bigNum2);
BigInteger compareMin = bigNum1.min(bigNum2);
}
取值
@Test
public void testToAnother() {
BigInteger bigNum = new BigInteger("52");
int radix = 2;
byte[] num1 = bigNum.toByteArray();
String num2 = bigNum.toString();
String num3 = bigNum.toString(radix);
int num4 = bigNum.intValue();
long num5 = bigNum.longValue();
float num6 = bigNum.floatValue();
double num7 = bigNum.doubleValue();
}
处理大数浮点数
BigDecimal
大体的操作方法类似。 只是注意几点 就是除法,和注意保留小数的
public static void main(String[] args)
{
BigDecimal a = new BigDecimal("4.5635");
a = a.setScale(3, RoundingMode.HALF_UP);
System.out.println(a);
}
ROUND_CEILING
ROUND_DOWN
ROUND_FLOOR
ROUND_HALF_DOWN
ROUND_HALF_EVEN
ROUND_HALF_UP
ROUND_UNNECESSARY
ROUND_UP
例题
思路很简单,就是大数问题嘛
package com.huterox.test03;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
public class 复数幂
{
public static void main(String[] args) throws FileNotFoundException
{
PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream("复幂数.txt")));
BigInteger a = BigInteger.valueOf(2);
BigInteger b = BigInteger.valueOf(3);
BigInteger x = BigInteger.valueOf(2);
BigInteger y = BigInteger.valueOf(3);
for(int i=2;i<=123456;++i)
{
BigInteger t1 = a.multiply(x);
BigInteger t2 = a.multiply(y);
BigInteger t3 = b.multiply(x);
BigInteger t4 = b.multiply(y);
x = t1.subtract(t4);
y = t2.add(t3);
}
out.println(x.toString()+y.toString()+"i");
out.close();
}
}
|