O problema de grandes números em Java


Java é bom ou não, mas tem um problema fatal em relação a linguagens dinâmicas como Python, ou seja, alguns problemas causados ​​por tipos. Como Java é uma linguagem semiestática, quando uma variável é declarada, ela será armazenada na memória de acordo com o tipo. Abra uma memória para você. Aí vem o problema, se meu número for muito grande, é bem fácil estourar. Alguns tópicos dizem que você pode tirar o excedente, mas e se você não disser. Então apenas números grandes podem ser considerados. Isso nos deixa com muitas questões a considerar.

Felizmente, existe na verdade uma API para lidar com grandes números em Java. O princípio de implementação central é, na verdade, o mesmo que nosso interpretador Python implementando Python 1+1.
Vamos falar um pouco aqui sobre como é difícil implementar 1+1 no interpretador Python. Antes de tudo Python é uma linguagem dinâmica, obviamente você não precisa declarar seus tipos de variáveis. Então você é legal quando escreve, então como o interpretador sabe que tipo de variável são suas variáveis? Todos nós sabemos que a camada inferior do Python é a linguagem C ou Java. Claro, depende de qual interpretador você usa, geralmente C Assim, em essência, quando o código Python está em execução, na verdade é um programa em linguagem C em execução, inferindo seu código Python.

Todos nós sabemos que Java pode ser pré-compilado, então as dicas de código da sua ideia são muito boas, mas Python não é, ele é dinâmico, então você descobre que as dicas de código do seu pycharm não são tão boas quanto a sua ideia. ok, vamos ver primeiro o que o interpretador fez. Em primeiro lugar, não há dúvidas de que como sou um programa em linguagem C executando código, naturalmente preciso inferir o tipo de variável em seu código Python, por exemplo, você é do tipo int Sim, e então eu vou usar o programa em linguagem C para alocar espaço para você. O problema é que, para usuários de Python, ele só se importa com os números que eu coloco nele, e não se importa se nossas variáveis ​​vão transbordar ou não. O fato é Quando eu estava no ensino médio, não pensava em problemas de overflow até me deparar com a linguagem C. Portanto, o interpretador da linguagem C também precisa julgar o comprimento do valor desse tipo, uma vez que é muito longo, deve usar o método do número grande para lidar com ele. Por exemplo, ele irá solicitar um array para armazenar, que também está nessa API do Java. (foto abaixo) Então você vê que o programa Python é muito forte. Então, os programadores python são bons, mas a engenharia desses dois bens é mais difícil de controlar. Embora Java seja prolixo, você pode escrever código que pode ler mesmo se for um novato, mas tente Python. Portanto, muitas pessoas reclamam que escrever alguns milhares de linhas de Python não é suficiente, de fato, como a quantidade desse projeto se tornou maior, é difícil para pessoas com níveis mais baixos controlá-lo bem. É claro que a falta de prontidão do código também é um problema, mas como a sintaxe a:int é suportada posteriormente, a situação melhorou um pouco, mas a engenharia ainda é um problema.

insira a descrição da imagem aqui

OK, sem fofocas, é hora de fazer alguma coisa.

Manipulando números inteiros grandes

BigInteger

Esta é uma versão built-in e muito antiga, então não se preocupe com o copo de ponte azul jdk1.7 não pode ser usado, mas o aprimorado para parece ser posterior a 1.8, isso deve ser observado.
O uso deste BIgInteger é realmente muito simples. Tudo o que precisamos prestar atenção
é como usar BigInteger para operações. Porque neste momento não podemos diretamente + - * /.

atribuir

Existem dois métodos

BigInteger a= new BigInteger("1234567890");
BigInteger b = BigInteger.valueOf("123457890)

adição, subtração, multiplicação e divisão

a.add(b);
a.subtract(b);
a.multiply(b);
a.divide(b)

Encontre a função de exponenciação, encontre o divisor comum

a.pow(2)
a.gcd(b) a,b的最大公约数

E claro a.abs()

julgamento comparativo

comerPara()

compareTo() retorna um tipo de dado int: 1 é maior que; 0 é igual a; -1 é menor que;
max(), min(): retorna os dados grandes (pequenos) BigInteger respectivamente;

	//比较大小:compareTo(),max(),min()
	@Test
	public void testCompare() {
    
    
		BigInteger bigNum1 = new BigInteger("52");
		BigInteger bigNum2 = new BigInteger("27");

		//1.compareTo():返回一个int型数据(1 大于; 0 等于; -1 小于)
		int num = bigNum1.compareTo(bigNum2);			

		//2.max():直接返回大的那个数,类型为BigInteger
		//	等价:return (compareTo(val) > 0 ? this : val);
		BigInteger compareMax = bigNum1.max(bigNum2);	

		//3.min():直接返回小的那个数,类型为BigInteger
		//	等价:return (compareTo(val) < 0 ? this : val);
		BigInteger compareMin = bigNum1.min(bigNum2);	
	}

valor


	@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);//转化为2进制
	
		int num4 = bigNum.intValue();

		long num5 = bigNum.longValue();

		float num6 = bigNum.floatValue();
	
		double num7 = bigNum.doubleValue();
	}

Manipulando grandes números de ponto flutuante

BigDecimal

O método geral de operação é semelhante.
Apenas preste atenção em alguns pontos
, ou seja, divisão, e preste atenção em manter os decimais

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

        a = a.setScale(3, RoundingMode.HALF_UP);    //保留3位小数,且四舍五入
        System.out.println(a);
    }
ROUND_CEILING    //向正无穷方向舍入

ROUND_DOWN    //向零方向舍入

ROUND_FLOOR    //向负无穷方向舍入

ROUND_HALF_DOWN    //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5

ROUND_HALF_EVEN    //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP,如果是偶数,使用ROUND_HALF_DOWN

ROUND_HALF_UP    //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6

ROUND_UNNECESSARY    //计算结果是精确的,不需要舍入模式

ROUND_UP    //向远离0的方向舍入

exemplo

insira a descrição da imagem aqui

A ideia é muito simples, é o problema dos grandes números

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(); 
    }

}

Acho que você gosta

Origin blog.csdn.net/FUTEROX/article/details/123661058
Recomendado
Clasificación