Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将用作BigInteger类型的int数组转换为";“可读性”;一串_Java_String_Debugging_Math_Biginteger - Fatal编程技术网

Java 如何将用作BigInteger类型的int数组转换为";“可读性”;一串

Java 如何将用作BigInteger类型的int数组转换为";“可读性”;一串,java,string,debugging,math,biginteger,Java,String,Debugging,Math,Biginteger,我正在尝试实现bigingers的一些功能,作为个人编程练习 与许多实现一样,我使用int[]作为无符号整数 我想实现一些基本功能,比如加法、减法、乘法、除法,但我遇到的问题是,为了调试,我需要从数据结构中获取一个“人类可读的”toString,以便更好地检查和理解我在做什么 我觉得我被卡住了。我不相信我的算法是正确的,但我没有办法检查它 我看过一些实现,比如ApacheHarmony或OpenJDK,但是它们用来创建字符串的算法看起来比实际的加号、减号、。。。等等 当然,我可以使用其中一个复杂

我正在尝试实现
biginger
s的一些功能,作为个人编程练习

与许多实现一样,我使用
int[]
作为无符号整数

我想实现一些基本功能,比如加法、减法、乘法、除法,但我遇到的问题是,为了调试,我需要从数据结构中获取一个“人类可读的”
toString
,以便更好地检查和理解我在做什么

我觉得我被卡住了。我不相信我的算法是正确的,但我没有办法检查它

我看过一些实现,比如ApacheHarmony或OpenJDK,但是它们用来创建字符串的算法看起来比实际的加号、减号、。。。等等

当然,我可以使用其中一个复杂的工具,但如果我自己已经无法实现它,我至少希望能够理解它的实现

有人能推荐一个将
int[]
转换为字符串的简单实现吗


示例:
newint[]{Integer.MAX_VALUE,1}
应被视为一个大的无符号数字并打印:
8589934590
(基本上是2个字符)。

首先实现到十六进制的转换器,并在开发的初始阶段使用十六进制作为人类可读的格式。执行十六进制很容易,因为您不需要实现除法:只需将单个项目转换为十六进制,将它们粘合在一起,就完成了

除法算法就位后,您可以通过通常的“获取余数%10并除掉”方法实现到十进制格式的转换。

我将使用这种方法:

  • 你没有提到你如何存储零;它可能需要特殊处理,在这种情况下,您可以在继续执行其余算法之前对其进行特殊处理
  • 复制
    int[]
    ;称之为
    iArr
    。此算法的其余部分将在
    iArr
    上运行
  • 创建一个足够大的
    char[]
    -称之为
    s
    。由于
    int
    最多可以有十位数字,因此可以使用
    s=new char[iArr.length*10]
  • 从位置
    int i=s.length-1开始。通过
    iArr
    ,除以10,将余数加上
    '0'
    存储在
    s[i]
    中。然后递减
    i
    。重复此过程,直到
    iArr
    为零。(除以10的逻辑大致是:将每个元素除以10,并记下余数。在将该元素除以10之前,将余数乘以Integer.MAX_INT+1
    ,添加到下一个元素。不用说,您需要使用
    long
    进行数学计算)
  • 您的结果是
    新字符串(s,i,s.length-i)
为了提高效率:

  • 您可以用10的幂除,例如
    1000000
    或诸如此类的运算,一次得到一组数字(显然这会使
    char
    的处理更复杂)
  • 当您将
    iArr
    的前导元素归零时,您可以跟踪第一个非零元素的位置,并忽略之前的任何元素
但实际上这两个都不是必要的


编辑以添加实际代码。该计划:

public class Main
{
    private static final long RADIX = -2L * (long)Integer.MIN_VALUE;

    public static void main(final String... args)
    {
        System.out.println(stringify(new int[]{0})); // 0
        System.out.println(stringify(new int[]{1})); // 1
        System.out.println(stringify(new int[]{Integer.MAX_VALUE})); // 2^31-1
        System.out.println(stringify(new int[]{Integer.MIN_VALUE})); // 2^31
        System.out.println(stringify(new int[]{-1})); // 2^32-1
        System.out.println(stringify(new int[]{1, 0})); // 2^32
        System.out.println(stringify(new int[]{1, -1})); // 2^33-1
        System.out.println(stringify(new int[]{-1, -1})); // 2^64-1
        System.out.println(stringify(new int[]{1, 0, 0})); // 2^64
    }

    private static String stringify(final int[] _iArr)
    {
        final int[] iArr = new int[_iArr.length];
        System.arraycopy(_iArr, 0, iArr, 0, _iArr.length);
        final char[] ret = new char[10 * iArr.length];
        int retIndex = ret.length;
        while(true)
        {
            boolean isZero = true;
            int carry = 0;
            for(int i = 0; i < iArr.length; ++i)
            {
                long val = unsignedInt2Long(iArr[i]);
                if(val != 0L)
                    isZero = false;
                val += carry * RADIX;
                carry = (int) (val % 10L);
                val /= 10L;
                iArr[i] = long2UnsignedInt(val);
            }
            if(isZero)
            {
                if(retIndex == ret.length)
                    return "0";
                else
                    return new String(ret, retIndex, ret.length - retIndex);
            }
            assert(retIndex > 0);
            ret[--retIndex] = (char) (carry + (int)'0');
        }
    }

    private static long unsignedInt2Long(final int unsignedInt)
    {
        if(unsignedInt >= 0)
            return unsignedInt;
        else
            return unsignedInt + RADIX;
    }

    private static int long2UnsignedInt(final long _long)
    {
        assert(_long >= 0L);
        assert(_long < RADIX);
        if(_long <= (long) Integer.MAX_VALUE)
            return (int) _long;
        else
            return (int) (_long - RADIX);
    }
}

(但您必须检查
main
方法及其注释,以确认我正确理解了您打算如何存储这些整数。)

您能给出几个
int[]
s示例和预期的输出字符串吗?太好了!谢谢,我会努力实现的!您的实现采用哪种顺序?
数字[0]
是最低位还是最高位?有没有推荐的方法来实现它?
s[0]
是最重要的位置(因为这是
新字符串(…)
所期望的)。叹气我无法让它工作:-(我觉得我太傻了……你能告诉我循环应该是什么样子吗?@soc:你能给我一个关于如何存储这些整数的精确定义吗?你说你存储的是一个“无符号整数”。这是否意味着数组中的每个元素都是正的?还是意味着使用的偏移量为
Integer.MIN_VALUE
(因此,
Integer.MIN_VALUE
表示零,零表示
Integer.MAX_VALUE+1
Integer.MAX_VALUE
表示
2*Integer.MAX_VALUE+1
)还是别的什么?@soc:还有,这是“小端点”还是“大端点”?
{1,0}
等同于
{1}
(小端点:LSB优先),还是
{0,1}
等同于
{1}
(大端点:MSB优先)?
0
1
2147483647
2147483648
4294967295
4294967296
8589934591
18446744073709551615
18446744073709551616