Java vs. C#:BigInteger十六进制字符串产生不同的结果? [英] Java vs. C#: BigInteger hex string yields different result?
问题描述
问:
这个代码的Java:
的BigInteger MOD =新的BigInteger(86f71688cdd2612ca117d1f54bdae029,16);
产生(在Java)的数量
179399505810976971998364784462504058921
然而,当我使用C#,
BigInteger的MOD = BigInteger.Parse(86f71688cdd2612ca117d1f54bdae029,System.Globalization.NumberStyles.HexNumber); //基地16
我没有得到相同的号码,我得到:
-160882861109961491465009822969264152535
然而,当我直接从十进制创建的数量,它的工作原理
BigInteger的MOD = BigInteger.Parse(179399505810976971998364784462504058921);
我试图从反向转换十六进制字符串字节数组和扭转它,并创建一个BigInteger阵,以防万一它是一个字节数组字节顺序不同,但没有帮助...
转换的Java代码到C#的时候我也遇到了以下问题:
的Java
的BigInteger K0 =新的BigInteger(字节[]);
要获得在C#中相同的号码,我必须扭转,因为在BigInteger的实现不同字节数组
C#等效的:
的BigInteger K0 =新的BigInteger(字节[ ] .Reverse()ToArray的())。
下面的MSDN说,有关的 BigInteger.Parse
:
如果值是一个十六进制字符串,在
解析(字符串的NumberStyles)
法解释值作为通过使用两个的补码表示存储如果前两个十六进制数字大于或等于 0x80的负数。换句话说,该方法将解释第一字节的最高阶位的值作为符号位。为了确保一个十六进制字符串被正确解释为正数,在值的第一个数字必须有一个零值。例如,该方法解译 0x80的为负值,但它解释为 0x080 或 0x0080 为正值。
块引用>
所以,添加一个
0
在解析十六进制数的前面给力一个无符号的诠释。
至于往返Java和C#之间的字节数组代表一个大的整数,我建议不要,除非你真的不得不这样做。但是,这两种实现的发生的使用兼容的二进制补码表示,如果解决字节顺序问题。
的 MSDN说:
此方法返回数组中的单个字节出现在小尾数订单。也就是说,该值的低位字节先于高阶字节。数组的第一个字节反映了
的BigInteger
值的前八位,第二个字节反映未来八年位,等等。
块引用>
的 Java文档说:
返回包含的这个二进制补码表示<字节数组code>的BigInteger 。的字节数组将在大端字节顺序:最显著字节在第零个元素
块引用>Question:
This code in Java:
BigInteger mod = new BigInteger("86f71688cdd2612ca117d1f54bdae029", 16);
produces (in java) the number
179399505810976971998364784462504058921
However, when I use C#,
BigInteger mod = BigInteger.Parse("86f71688cdd2612ca117d1f54bdae029", System.Globalization.NumberStyles.HexNumber); // base 16
i don't get the same number, I get:
-160882861109961491465009822969264152535
However, when I create the number directly from decimal, it works
BigInteger mod = BigInteger.Parse("179399505810976971998364784462504058921");
I tried converting the hex string in a byte array and reversing it, and creating a biginteger from the reversed array, just in case it's a byte array with different endianness, but that didn't help...
I also encountered the following problem when converting Java-Code to C#:
JavaBigInteger k0 = new BigInteger(byte[]);
to get the same number in C#, I must reverse the array because of different Endianness in the biginteger implementation
C# equivalent:
BigInteger k0 = new BigInteger(byte[].Reverse().ToArray());
解决方案Here's what MSDN says about
BigInteger.Parse
:If value is a hexadecimal string, the
Parse(String, NumberStyles)
method interprets value as a negative number stored by using two's complement representation if its first two hexadecimal digits are greater than or equal to 0x80. In other words, the method interprets the highest-order bit of the first byte in value as the sign bit. To make sure that a hexadecimal string is correctly interpreted as a positive number, the first digit in value must have a value of zero. For example, the method interprets 0x80 as a negative value, but it interprets either 0x080 or 0x0080 as a positive value.So, add a
0
in front of the parsed hexadecimal number to force an unsigned interpretation.As for round-tripping a big integer represented by a byte array between Java and C#, I'd advise against that, unless you really have to. But both implementations happen to use a compatible two's complement representation, if you fix the endianness issue.
The individual bytes in the array returned by this method appear in little-endian order. That is, the lower-order bytes of the value precede the higher-order bytes. The first byte of the array reflects the first eight bits of the
BigInteger
value, the second byte reflects the next eight bits, and so on.Returns a byte array containing the two's-complement representation of this
BigInteger
. The byte array will be in big-endian byte-order: the most significant byte is in the zeroth element.
这篇关于Java vs. C#:BigInteger十六进制字符串产生不同的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!