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开始。通过
,除以10,将余数加上iArr
存储在'0'
中。然后递减s[i]
。重复此过程,直到i
为零。(除以10的逻辑大致是:将每个元素除以10,并记下余数。在将该元素除以10之前,将余数乘以Integer.MAX_INT+1iArr
进行数学计算)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