如何将java BigDecimal转换为普通字节数组(不是2的补码)

发布于 2024-11-10 11:30:44 字数 1719 浏览 7 评论 0原文

如何将大整数转换为非 2 补码格式的字节数组。基本上我只需要转换正数,不需要符号位。

所以像 10 这样的东西会变成一个字节 0x0a 即-> 00001010

[更新] 根据评论,我尝试了这个

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;
}

,我得到的输出值为 -19720446 并且使用 //int val = (int) b & 0xFF;取消注释并用作被加数,我得到的值是 4292024066

[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);
}

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.

So something like 10 would become a byte 0x0a i.e-> 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

[Update2]
Here is a test I ran which works. Not sure if it is bug free but looks fine.

@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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

柳絮泡泡 2024-11-17 11:30:44

差异主要是概念性的。无符号数与 2 的补码相同。 2 的恭维只是描述了如何表示你说你没有的负数。

即 10 在有符号和无符号表示中都是 00001010。

要从 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);

打印

[2, 23, -45, -1]
35116031

字节是正确的并再现相同的值。

重建 BigInteger 的方式存在错误。当 Java 通常使用大尾数法时,您假设字节序列化是小尾数法 http://en.wikipedia.org/wiki /字节顺序

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.

i.e. 10 is 00001010 in signed and unsigned representation.

To get the bytes from a BigDecimal or BigInteger you can use the methods it provides.

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

迷乱花海 2024-11-17 11:30:44

尝试以字节为单位分割数字,在每次迭代中除以 256 并使用余数,并将所有这些字节放入一个数组中。

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.

正数的 2-compliment 中的符号位为 0,

因此有符号或无符号都不是 0对正数产生影响

the sign bit in 2-compliment for positive numbers is 0

so signed or unsigned doesn't make a difference for positive numbers

小瓶盖 2024-11-17 11:30:44

如果该值小于 long 的大小,则使用 longValue,然后将 long 切成字节。如果该值大于 long,那么您可能需要使用迭代方法,重复将数字除以 256,将余数作为下一个字节,然后重复直到得到零。字节将从右到左生成。有符号数需要思考(以生成 2 补码结果),但也并不复杂。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文