将大整数二进制转换为大整数数字?

4

目前我正在使用 Long 整数类型。我使用以下代码转换二进制/数字之间的值:

Convert.ToInt64(BinaryString, 2); //Convert binary string of base 2 to number
Convert.ToString(LongNumber, 2); //Convert long number to binary string of base 2

现在我使用的数字已经超过了64位,因此我开始使用BigInteger。我似乎找不到上面代码的等效版本。

如何将一个超过64位的二进制字符串转换为BigInteger数字,反之亦然?

更新:

答案中的参考文献包含我想要的答案,但我在从Number到Binary的转换中遇到了一些问题。

我已经使用了第一个参考文献中提供的以下代码:

    public static string ToBinaryString(this BigInteger bigint)
    {
        var bytes = bigint.ToByteArray();
        var idx = bytes.Length - 1;

        // Create a StringBuilder having appropriate capacity.
        var base2 = new StringBuilder(bytes.Length * 8);

        // Convert first byte to binary.
        var binary = Convert.ToString(bytes[idx], 2);

        // Ensure leading zero exists if value is positive.
        if (binary[0] != '0' && bigint.Sign == 1)
        {
            base2.Append('0');
        }

        // Append binary string to StringBuilder.
        base2.Append(binary);

        // Convert remaining bytes adding leading zeros.
        for (idx--; idx >= 0; idx--)
        {
            base2.Append(Convert.ToString(bytes[idx], 2).PadLeft(8, '0'));
        }

        return base2.ToString();
    }

我得到的结果是错误的:
100001000100000000000100000110000100010000000000000000000000000000000000 ===>  2439583056328331886592
2439583056328331886592 ===> 0100001000100000000000100000110000100010000000000000000000000000000000000

如果你将得到的二进制字符串排列在一起,你会发现转换是正确的,问题在于左边有一个前导零:

100001000100000000000100000110000100010000000000000000000000000000000000
0100001000100000000000100000110000100010000000000000000000000000000000000

我试着阅读代码中提供的解释并对其进行更改,但没有成功。

更新2:

我通过在代码中更改以下内容来解决了这个问题:

        // Ensure leading zero exists if value is positive.
        if (binary[0] != '0' && bigint.Sign == 1)
        {
            base2.Append('0');

            // Append binary string to StringBuilder.
            base2.Append(binary);
        }
3个回答

6

我更新了问题,请看一下我面临的问题。 - ykh

0

MSDN上有一个关于BigIntegers的好参考资料,你能看一下吗? https://msdn.microsoft.com/zh-cn/library/system.numerics.biginteger(v=vs.110).aspx

此外还有一篇文章介绍如何将二进制转换为BigIntegers 将存储在整数列表(小端)中的二进制表示转换为BigIntegers

这个例子来自MSDN。

string positiveString = "91389681247993671255432112000000";
string negativeString = "-90315837410896312071002088037140000";
BigInteger posBigInt = 0;
BigInteger negBigInt = 0;

try {
   posBigInt = BigInteger.Parse(positiveString);
   Console.WriteLine(posBigInt);
}
catch (FormatException)
{
   Console.WriteLine("Unable to convert the string '{0}' to a BigInteger value.", 
                     positiveString);
}

if (BigInteger.TryParse(negativeString, out negBigInt))
  Console.WriteLine(negBigInt);
else
   Console.WriteLine("Unable to convert the string '{0}' to a BigInteger value.", 
                      negativeString);

// The example displays the following output:
//   9.1389681247993671255432112E+31
//   -9.0315837410896312071002088037E+34

2
这些不是二进制数字串。这个问题非常特定,涉及到“基数为2的字符串”的处理。 - Ben Voigt
1
这篇帖子里面有一个答案,这是你想要的吗?http://stackoverflow.com/questions/22947412/conversion-of-a-binary-representation-stored-in-a-list-of-integers-little-endia - Ugur Basak

0
这可能会有用。
使用方法:
string someString = "-1101010001"; // More examples: 1_1111_0101, +100101101
bool success = TryParseBinary(someString, out BigInteger outBigInt);

功能:

static bool TryParseBinary(ReadOnlySpan<char> input, out BigInteger result)
{
    int inputLen = input.Length;

    byte[] bytes = new byte[(inputLen + 7) / 8];
    int outputBitPosition = 0; // The current bit we 
                               // are writing to.

    // If it starts with a '-' then set 
    // negative rawValue to zero.
    bool isNeg = input[0] == '-'; // 0x2D;

    // If starting with a - or + then 
    // set headPosition to 1.
    int headPosition = isNeg | input[0] == '+' ? 1 : 0;

    int tailPosition = inputLen - 1;
    for (; tailPosition >= headPosition; tailPosition--)
    {
        switch (input[tailPosition])
        {
            case '1':
                bytes[outputBitPosition >> 3] |= 
                    (byte)(1 << (outputBitPosition & 0x7));
                goto case '0';

            case '0':
                outputBitPosition++;
                break;

            // Allow commas, '_' (i.e., 1111_1111_0000), 
            // and spaces
            case ',' or '_' or ' ':  
                break;

            default:
                result = new BigInteger(0);
                return false; // Function was not successful - 
                              // unsupported char found
        }
    }

    // If the number is negative, let's perform 
    // two's complement: (1) invert the 
    // bits (2) add 1
    if (isNeg)
    {
        int byteCount = bytes.Length;

        //   (1) Invert the bits
        for (int i = 0; i < byteCount; i++)
        {
            bytes[i] ^= 0xff;
        }

        //   (2) Increment the LSB and increment more 
        //       significant bytes as needed.
        bytes[0]++;
        for (int i = 0; bytes[i] == 0; i++)
        {
            if (i + 1 >= byteCount)
            {
                break;
            }

            bytes[i + 1]++;
        }
    }

    result = new(bytes, !isNeg);

    // Return true if success. If no 0/1 bits 
    // found then return false.
    return outputBitPosition != 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接