Java 如何将大整数转换为二进制?

Java 如何将大整数转换为二进制?,java,algorithm,binary,integer,largenumber,Java,Algorithm,Binary,Integer,Largenumber,很抱歉可能会出现重复的帖子,我在这里看到了许多类似的主题,但没有一个是我真正需要的。在实际发布一个问题之前,我想明确说明这个问题不是家庭作业 所以问题是:如何将大整数转换成二进制表示?整数足够大,可以放入基元类型(不能使用Java long)。输入可以表示为字符串格式或数字数组。免责声明,这不是生产级别的解决方案,所以我不想使用BigInteger类。相反,我想实现一个算法 到目前为止,我采用了以下方法: 以字符串表示的输入和输出值。如果输入的最后一位是偶数,则在输出前加上“0”,否则-加上“1

很抱歉可能会出现重复的帖子,我在这里看到了许多类似的主题,但没有一个是我真正需要的。在实际发布一个问题之前,我想明确说明这个问题不是家庭作业

所以问题是:如何将大整数转换成二进制表示?整数足够大,可以放入基元类型(不能使用Java long)。输入可以表示为字符串格式或数字数组。免责声明,这不是生产级别的解决方案,所以我不想使用BigInteger类。相反,我想实现一个算法

到目前为止,我采用了以下方法: 以字符串表示的输入和输出值。如果输入的最后一位是偶数,则在输出前加上“0”,否则-加上“1”。之后,我将输入替换为输入除以2。我使用另一种方法-除以2进行算术除法。此过程在循环中运行,直到输入变为“0”或“1”。最后,我将输入前置到输出。代码如下:

辅助方法

/**
* @param s input integer value in string representation
* @return the input divided by 2 in string representation
**/
static String divideByTwo(String s)
{
    String result = "";
    int dividend = 0;
    int quotent = 0;
    boolean dividendIsZero = false;

    while (s.length() > 0)
    {
        int i = 1;          
        dividend = Character.getNumericValue(s.charAt(0));

        while (dividend < 2 && i < s.length())
        {
            if (dividendIsZero) {result += "0";}
            dividend = Integer.parseInt(s.substring(0, ++i));
        }

        quotent = dividend / 2;
        dividend -= quotent * 2;            
        dividendIsZero = (dividend == 0);

        result += Integer.toString(quotent);
        s = s.substring(i);

        if (!dividendIsZero && s.length() != 0)
        {
            s = Integer.toString(dividend) + s;
        }
    }
    return result;      
}
如您所见,运行时为O(n^2)。O(n)表示整数二进制方法,O(n)表示在循环内部运行的除以二。有没有办法实现更好的运行时?提前谢谢

试试这个:

new BigDecimal("12345678901234567890123456789012345678901234567890").toString(2);
编辑:

为了上一堂大数字课,你可能想看看我一周前关于这个的帖子。啊,问题是你提的,没关系

不同数字系统之间的转换原则上是重复的“除、余、乘、加”操作。让我们看一个例子:

我们想把123从十进制转换成基数为3的数字。我们该怎么办

Take the remainder modulo 3 - prepend this digit to the result.
Divide by 3.
If the number is bigger than 0, continue with this number at step 1
看起来是这样的:

123 % 3 == 0. ==> The last digit is 0.
123 / 3 == 41.
41 % 3 == 2 ==> The second last digit is 2.
41 / 3 == 13
13 % 3 == 1 ==> The third digit is 1.
13 / 3 == 4
4 % 3 == 1 ==> The fourth digit is 1 again.
4 / 3 == 1
1 % 3 == 1 ==> The fifth digit is 1.
结果是11120

问题是,对于这一点,你需要已经有了某种十进制格式的3除法,如果你不以十进制格式实现你的数字(就像我在上面链接的上一个问题的答案中所做的那样),通常情况下就不会这样

但它可以将内部数字格式转换为任何外部格式

那么,让我们来看看如何进行从11120(基数3)到其十进制等价物的逆计算。(以3为基数表示任意基数的占位符,以10为基数表示内部基数的占位符。)原则上,这个数字可以写成:

1*3^4+1*3^3+1*3^2+2*3^1+0*3^0

更好的方法(计算速度更快)是:

(((1*3)+1)*3+1)*3+2)*3+0 1. 3. 4. 12 13 39 41 123 123

(这称为Horner方案,通常用于计算多项式的值。)

如果您知道如何表示目标系统中的输入基数(和数字),则可以在正在实现的数字方案中实现这一点


(我刚刚在我的DecimalBigInt类中添加了这样的计算,但您可能希望直接在内部数据结构中进行计算,而不是为要输入的每个十进制数字创建BigNumber类的新对象(甚至两个对象)。

在简单方法中,有两种可能的方法(此处显示的所有数字均为十进制)

  • 按照问题中所述,在每一步中以十进制计算并除以2
  • 以二进制形式工作,并在每个步骤中乘以10,例如
    123=((1*10)+2)*10+3
  • 如果您使用的是二进制计算机,那么方法2可能更容易

    有关该主题的更深入的讨论,请参见示例。

    中说:

    对于非常大的数字,这些简单的方法效率很低,因为 它们执行大量乘法或除法,其中 操作数非常大。一个简单的分治算法更有用 渐近有效:给定一个二进制数,它除以 10^k,其中k的选择使商大致等于 余数;然后将这些片段中的每一个转换为十进制,并将 两个是串联的。给定一个十进制数,可以将其拆分为两个 大小大致相同的片段,每个片段都转换为二进制, 因此,将第一个转换件乘以10^k并添加到 第二个转换件,其中k是 第二个,转换前最不重要的部分


    我已经尝试过了,对于大于10000位的数字,这种方法比传统的方法快。

    非常感谢您,S Harish Morampudi提供了即时答案,但我不想使用BigInteger类。我想实现算法。因此,如果我理解正确,请不同数字系统之间的转换原则上是一个重复的除法、余数、乘法、加法运算,那么O(n^2)是下限。是这样吗?
    123 % 3 == 0. ==> The last digit is 0.
    123 / 3 == 41.
    41 % 3 == 2 ==> The second last digit is 2.
    41 / 3 == 13
    13 % 3 == 1 ==> The third digit is 1.
    13 / 3 == 4
    4 % 3 == 1 ==> The fourth digit is 1 again.
    4 / 3 == 1
    1 % 3 == 1 ==> The fifth digit is 1.