如何将 java BigDecimal 转换为普通字节数组(不是 2 的补码)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6167697/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert java BigDecimal to normal byte array (not 2's complement)
提问by Abe
How do I convert from big integer to a byte array which is not in 2's complement format. Bascially I only need to convert positive numbers and do not need the sign bit.
如何从大整数转换为非 2 的补码格式的字节数组。基本上我只需要转换正数,不需要符号位。
So something like 10 would become a byte 0x0a i.e-> 00001010
所以像 10 这样的东西会变成一个字节 0x0a ie-> 00001010
[Update]As per comment I tried this
[更新]根据评论我试过这个
public void testBinary()
{
BigDecimal test = new BigDecimal(35116031);
BigInteger theInt = test.unscaledValue();
byte[] arr = theInt.toByteArray();
System.out.println(getCounterVal(arr, new BigInteger("256")));
}
public BigInteger getCounterVal(byte[] arr, BigInteger multiplier)
{
BigInteger counter = BigInteger.ZERO;
for(int i = (arr.length - 1); i >=0; i--)
{
int b = arr[i];
//int val = (int) b & 0xFF;
BigInteger augend = BigInteger.valueOf(b);
counter = counter.add(augend.multiply(multiplier.pow(i)));
}
return counter;
}
The out put value I got was -19720446 And with the //int val = (int) b & 0xFF; uncommented and used as augend, I got the value 4292024066
我得到的输出值是 -19720446 并且 //int val = (int) b & 0xFF; 取消注释并用作被加数,我得到了值 4292024066
[Update2]Here is a test I ran which works. Not sure if it is bug free but looks fine.
[Update2]这是我运行的一个测试。不确定它是否没有错误,但看起来不错。
@Test
public void bigIntegerToArray()
{
BigInteger bigInt = new BigInteger("35116444");
byte[] array = bigInt.toByteArray();
if (array[0] == 0)
{
byte[] tmp = new byte[array.length - 1];
System.arraycopy(array, 1, tmp, 0, tmp.length);
array = tmp;
}
BigInteger derived = BigInteger.ZERO;
BigInteger twofiftysix = new BigInteger("256");
int j = 0;
for (int i = array.length - 1; i >= 0; i--)
{
int val = (int) array[i] & 0xFF;
BigInteger addend = BigInteger.valueOf(val);
BigInteger multiplier = twofiftysix.pow(j);
addend = addend.multiply(multiplier);
derived = derived.add(addend);
j++;
}
Assert.assertEquals(bigInt, derived);
}
回答by Peter Lawrey
The difference is largely conceptual. Unsigned numbers are the same in 2's compliment. 2's compliment just describes how to represent negative numbers which you say you don't have.
差异主要是概念上的。无符号数在 2 的恭维中是相同的。2 的赞美只是描述了如何表示您说没有的负数。
i.e. 10 is 00001010 in signed and unsigned representation.
即 10 在有符号和无符号表示中是 00001010。
To get the bytes from a BigDecimal or BigInteger you can use the methods it provides.
要从 BigDecimal 或 BigInteger 获取字节,您可以使用它提供的方法。
BigDecimal test = new BigDecimal(35116031);
BigInteger theInt = test.unscaledValue();
byte[] arr = theInt.toByteArray();
System.out.println(Arrays.toString(arr));
BigInteger bi2 = new BigInteger(arr);
BigDecimal bd2 = new BigDecimal(bi2, 0);
System.out.println(bd2);
prints
印刷
[2, 23, -45, -1]
35116031
The bytes are correct and reproduce the same value.
字节是正确的并重现相同的值。
There is a bug in the way you rebuild your BigInteger. You assume the byte serialization is little endian when Java typically uses big endian http://en.wikipedia.org/wiki/Endianness
您重建 BigInteger 的方式存在错误。当 Java 通常使用大端http://en.wikipedia.org/wiki/Endianness时,您假设字节序列化是小端
回答by Daniel
Try to split the number in bytes, by dividing by 256 in each iteration and using the remainder, and place all these bytes into an array.
尝试以字节为单位拆分数字,在每次迭代中除以 256 并使用余数,然后将所有这些字节放入一个数组中。
回答by ratchet freak
the sign bit in 2-complimentfor positive numbers is 0
正数的2-compliment 中的符号位是 0
so signed or unsigned doesn't make a difference for positive numbers
所以有符号或无符号对正数没有影响
回答by Hot Licks
If the value is less than the size of a long then use longValue, then chop the long into bytes. If the value is bigger than a long then probably you need to use an iterative approach, repeatedly dividing the number by 256, taking the remainder as the next byte, then repeating until you get zero. The bytes would be generated right to left. Signed numbers require thought (to generate 2s-complement results) but aren't much more complicated.
如果该值小于 long 的大小,则使用 longValue,然后将 long 切成字节。如果该值大于 long 则可能需要使用迭代方法,重复将数字除以 256,将余数作为下一个字节,然后重复直到得到零。字节将从右到左生成。带符号的数字需要思考(以生成 2s 补码结果),但并不复杂。