2015-09-05 33 views
2

问题:Java与C#:BigInteger十六进制字符串会产生不同的结果吗?

该代码在Java中:

BigInteger mod = new BigInteger("86f71688cdd2612ca117d1f54bdae029", 16); 

产生(在Java)的数量

179399505810976971998364784462504058921 

然而,当我使用C#,

BigInteger mod = BigInteger.Parse("86f71688cdd2612ca117d1f54bdae029", System.Globalization.NumberStyles.HexNumber); // base 16 

我不没有相同的号码,我得到:

-160882861109961491465009822969264152535 

然而,当我直接从十进制创建的数量,它的工作原理

BigInteger mod = BigInteger.Parse("179399505810976971998364784462504058921"); 

我试图转换十六进制字符串字节数组和扭转它,并创建一个从反向阵列的BigInteger,只是在情况下,它是一个字节数组不同字节,但没有帮助...

转换的Java代码到C#的时候我也遇到了以下问题:
的Java

BigInteger k0 = new BigInteger(byte[]); 

获得在C#中相同的号码,我必须扭转,因为在BigInteger的实现不同字节数组

C#相当于:

BigInteger k0 = new BigInteger(byte[].Reverse().ToArray()); 
+2

尝试在C#版本加入8前为零。 – RealSkeptic

+1

@RealSkeptic应该是一个答案;为我工作[这里](http://ideone.com/w3Ee5H)。 – bcsb1001

回答

7

这里的MSDN说怎么样BigInteger.Parse

如果值是一个十六进制字符串,则Parse(String, NumberStyles)方法将值解释为通过使用二进制补码表示形式存储的负数,如果其前两个十六进制数字s大于或等于0x80。换句话说,该方法将值中第一个字节的最高位解释为符号位。为确保十六进制字符串被正确解释为正数,第一个数字的值必须为零。例如,该方法将0x80解释为负值,但它将0x0800x0080解释为正值。

因此,在解析后的十六进制数前面加上0来强制进行未签名的解释。

至于在Java和C#之间往返一个由字节数组表示的大整数,我建议不要,除非你真的必须这样做。但是,如果您修复了字节顺序问题,那么两个实现都会发生以使用兼容的二进制补码表示法。

MSDN says

通过此方法返回的数组中的各个字节出现在小端顺序。也就是说,该值的低位字节在高位字节之前。数组的第一个字节反映BigInteger值的前八位,第二个字节反映后面的八位,依此类推。

Java docs say

返回一个包含该BigInteger的二进制补码表示的字节数组。字节数组将位于big-endian字节顺序:最重要的字节位于第零个元素中。

相关问题