如何将Java BigDecimal转换为普通字节数组(不是2的补码) [英] How to convert java BigDecimal to normal byte array (not 2's complement)

查看:145
本文介绍了如何将Java BigDecimal转换为普通字节数组(不是2的补码)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

因此,类似10的字节将变成字节0x0a,即-> 00001010

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

我得到的输出值为-19720446并且//int val =(int)b& 0xFF;没有注释并用作建议,我得到了值4292024066

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] 这是我运行的测试,可以正常工作.不知道它是否没有错误,但看起来还不错.

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

推荐答案

区别主要是概念上的.无符号数字与2的补语相同. 2的恭维只是描述了如何表示您没有的负数.

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.

即10是带符号和无符号表示形式的00001010.

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

要从BigDecimal或BigInteger获取字节,可以使用其提供的方法.

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

打印

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

这些字节是正确的,并且可以再现相同的值.

The bytes are correct and reproduce the same value.

重建BigInteger的方式存在错误.您假定Java通常使用大端字节时,字节序列化是小端字节 http://en.wikipedia.org/wiki/字节序

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

这篇关于如何将Java BigDecimal转换为普通字节数组(不是2的补码)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆