1. 程式人生 > >Java簡單高精度合集

Java簡單高精度合集

科學計數 uppercase 不可 ESS 必須 第一次 down pan 小數

第一個Java的算法程序。記得可以使用Alt+‘/‘自動補全sysout和main之類的。

BigInteger在java.math.BigInteger中。

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
        Scanner sc=new Scanner(System.in);
        
        BigInteger a=sc.nextBigInteger();
        BigInteger b
=sc.nextBigInteger(); BigInteger c=a.add(b); System.out.println(c); sc.close(); } }

順便把A*B也搞了,Java是有FFT優化的乘法。

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
        Scanner sc
=new Scanner(System.in); BigInteger a=sc.nextBigInteger(); BigInteger b=sc.nextBigInteger(); BigInteger c=a.multiply(b); System.out.println(c); sc.close(); } }

減法也就是變成subtract罷了。

斐波那契大數:

import java.math.BigInteger;
import
java.util.Scanner; public class Main { public static void main(String args[]) { Scanner sc=new Scanner(System.in); while(sc.hasNext()) { int n=sc.nextInt(); BigInteger f0=BigInteger.ONE; BigInteger f1=BigInteger.ONE; for(int i=1;i<n;i++) { BigInteger t=f1; f1=f0.add(f1); f0=t; } System.out.println(f1); } sc.close(); } }


https://www.luogu.org/problemnew/show/P1604

Java的高精度整數還有很多意想不到的神奇功能。例如BigInteger其實可以修改進制。

在讀入的時候先用String暫時保存結果,生成BigInteger的時候在第二個參數指定進制,在BigInteger的toString方法也可以指定進制。當需要進制轉換時使用String作為中轉就可以了。

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()) {
            int b=sc.nextInt();
            String sa=sc.next();
            String sb=sc.next();
        
            BigInteger ba=new BigInteger(sa,b);
            BigInteger bb=new BigInteger(sb,b);
            
            BigInteger bc=ba.add(bb);
            
            System.out.println(bc.toString(b).toUpperCase());
        }
        sc.close();
    }
}


要計算階乘的和,熟悉一下BigInteger的初始化方法以及與正常的整數運算的方法:

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()) {
            int n=sc.nextInt();
        
            BigInteger ans=BigInteger.ZERO;
            
            BigInteger fac=BigInteger.ONE;
            
            for(int i=1;i<=n;i++) {
                fac=fac.multiply(BigInteger.valueOf(i));
                ans=ans.add(fac);
            }
            
            System.out.println(ans);
        }
        sc.close();
    }
}


BigDecimal高精,註意BigDecimal的toString可能會出現科學計數法的結果。

註意!除法可能商是無限循環小數,這時候必須截斷!

public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode);

其中scale是小數點後的精度。

而roundingMode也就是舍入模式:

輸入RoundingMode.之後會出現如下:

CEILING    //向正無窮方向舍入
FLOOR    //向負無窮方向舍入

DOWN    //向零方向舍入
UP    //向遠離0的方向舍入

HALF_DOWN    //向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,向下舍入, 例如1.55 保留一位小數結果為1.5
HALF_UP    //向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,向上舍入, 1.55保留一位小數結果為1.6

HALF_EVEN    //向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,如果保留位數是奇數,使用ROUND_HALF_UP,如果是偶數,使用ROUND_HALF_DOWN

UNNECESSARY    //計算結果是精確的,不需要舍入模式

四舍五入就是是用

ROUND_HALF_UP

而直接設置截斷時,使用:

public static void main(String[] args)
{
    BigDecimal a = new BigDecimal("4.5635");

    a = a.setScale(3, RoundingMode.HALF_UP);    //保留3位小數,且四舍五入
    System.out.println(a);
}

第一次使用BigDecimal的題:

https://www.luogu.org/problemnew/show/P1517

import java.math.BigDecimal;
import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()) {
            BigDecimal x=sc.nextBigDecimal();
            int n=sc.nextInt();
            
            BigDecimal ans=BigDecimal.ONE;
            for(int i=0;i<n;i++) {
                ans=ans.multiply(x);
                //BigDecimal的乘法需要調用multiply()方法,乘以一個BigDecimal對象,返回一個BigDecimal對象
            }
            
            String s=ans.toPlainString();
            //在這裏要使用toPlainString()方法,默認的toString()方法在某些情況是科學計數法,錯了很多次才知道
            
            /*
             * 例如樣例:
             * 0.000001 5 
            */
            
            int len=s.length();
            int leadzero=-1;
            boolean metdot=false;
            for(int i=0;i<len;i++) {
                if(leadzero==-1&&s.charAt(i)!=‘0‘) {
                    leadzero=i;
                    //把整數部分的0去掉
                }
                if(s.charAt(i)==‘.‘) {
                    metdot=true;
                    //遇到了小數點,說明是小數
                    break;
                }
            }
            
            if(metdot==true) {
                s=s.substring(leadzero);
                //遇到了小數點,說明是小數
                len=s.length();
                //重新計算s的長度,因為前面可能截斷了整數部分的0
                int releadzero=-1;
                for(int i=len-1;i>=0;i--) {
                    if(s.charAt(i)!=‘0‘) {
                        releadzero=i+1;
                        //遇到第一個非零位置,其後的無效0截斷
                        if(s.charAt(i)==‘.‘) {
                            releadzero=i;
                            //遇到第一個非零位置是小數點,連小數點也截斷
                        }
                        break;
                    }
                }
                s=s.substring(0,releadzero);
            }
            else {
                //沒有遇到小數點,是整數,不可能有無效0
                ;
            }
            
            System.out.println(s);
        }
        sc.close();
    }
}

Java簡單高精度合集