简体   繁体   English

在不使用BigInteger的情况下处理Java中的大整数

[英]Handling large integers in Java without using BigInteger

I am currently working on an assignment that involves calculating Fibonacci numbers up to F(300) using a linear time complexity algorithm. 我目前正在从事一项任务,其中涉及使用线性时间复杂度算法来计算高达F(300)的斐波那契数。 I know via a quick search that a Java long will overflow at around F(93), so I am trying to figure out how to store such a large number. 通过快速搜索,我知道Java long将在F(93)附近溢出,因此我试图弄清楚如何存储这么大的数字。

However, our assignment states that we are not allowed to use language libraries such as BigInteger to store our numbers. 但是,我们的分配规定不允许我们使用BigInteger语言库来存储我们的数字。 We must write our own large integer data type or object. 我们必须编写自己的大整数数据类型或对象。

What exactly am I to do in this case? 在这种情况下,我该怎么办? I have never before had to write my own data type to handle something like a large integer. 我以前从未需要编写自己的数据类型来处理类似大整数的内容。 Is there some usual method of doing this? 有一些常用的方法吗?

I believe what you need is to create a data type out of primitive arrays, like int[] or long[] so that you store result value by bits across elements of this array. 我相信您需要从原始数组中创建数据类型,例如int []或long [],以便将结果值按位存储在此数组的各个元素之间。 Just like you can use two int's to store a long's bits you make take more ints to store a longer number. 就像您可以使用两个int来存储long的位一样,您也可以使用更多int来存储较长的数。

One problem though is to interpret this value, say, you wish to print the value - that would require an algorithm on its own, if a string like 2^n1 + 2^n2 + ... + 2^nk is not acceptable. 但是,一个问题是解释该值,例如,您希望打印该值-如果不可接受像2 ^ n1 + 2 ^ n2 + ... + 2 ^ nk这样的字符串,则需要单独使用该算法。

An example (using byte array to store decimal digits): 一个示例(使用字节数组存储十进制数字):

import java.util.ArrayList;
import java.util.List;


public final class HumongousInt {
public static HumongousInt of( String string ) {
    return new HumongousInt( asByteArray( string ) );
}

private static byte[] asByteArray( String string ) {
    int length = string.length();
    byte[] data = new byte[ length ];
    for( int i = 0; i < length; i++ ) {
        data[ i ] = asByte( string.charAt( i ) );
    }
    return data;
}

private static byte asByte( char c ) {
    if( c > '9' && c < '0' ) {
        throw new IllegalArgumentException( "Wrong numbe format only numbers 0-9 could be present" );
    }
    return ( byte ) ( c - '0' );
}

private final byte[] digits;

private HumongousInt( byte[] digits ) {
    this.digits = digits;
}

public HumongousInt add( HumongousInt other ) {
    int maxLength = Math.max( this.digits.length, other.digits.length );
    ArrayList< Byte > data = new ArrayList<>();
    int overhead = 0;
    int i = 1;
    while( overhead > 0 || ( i <= maxLength ) ) {
        int currentDigit = overhead;
        int thisIndex = ( this.digits.length - i );
        if( thisIndex >= 0 ) {
            currentDigit += this.digits[ thisIndex ];
        }
        int otherIndex = ( other.digits.length - i );
        if( otherIndex >= 0 ) {
            currentDigit += other.digits[ otherIndex ];
        }
        overhead = currentDigit / 10;
        data.add( Byte.valueOf( ( byte ) ( currentDigit %= 10 ) ) );
        i++;
    }
    return new HumongousInt( asInvertedByteArray( data ) );
}

private byte[] asInvertedByteArray( List< Byte > list ) {
    byte[] data = new byte[ list.size() ];
    for( int i = data.length - 1, j = 0; i >= 0; i--, j++ ) {
        data[ j ] = list.get( i );
    }
    return data;
}

public HumongousInt add( int i ) {
    return add( HumongousInt.of( Integer.toString( i ) ) );
}

@Override
public String toString() {
    StringBuilder builder = new StringBuilder( digits.length );
    for( byte b : digits ) {
        builder.append( b );
    }
    return ( digits[ 0 ] == ( byte ) 0 ) ? builder.substring( 1 ) : builder.toString();
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM