C#将大二进制字符串转换为十进制字符串并除以

问题描述

我想将一个大的二进制字符串转换为十进制字符串格式,然后除以一个整数。 (结果必须至少有 2 个小数位)。

例如

strBinary = "01010000010010110000001100000100000010100000000000000000000000000000000000000000101010000111100111011110010001100000101111000110110100101000101000011100010111000000000000000000000111000101110000000000000000000010011100000000000001110000000001100001011100110111001101100101011101000111001100101111011001000110010101110110011010010110001101100101011100110010111101100100011001010111011001101001011000110110010101011111011000010111001101110101011100110101111101111010011001010110111001110111011000010111010001100011011010000010111001101010011100000110011111111110110010100000000000000000000000000000000000000000111111111101100011111111111000010000000000011000010001010111100001101001011001100000000000000000010010010100100100101010000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111111101100000000000001000101000100011101010110001101101011011110010000000000000001000000000000010000000000000000000000000001000110000000000000000011111111111000010000001100101101011010000111010001110100011100000011101000101111001011110110111001110011001011100110000101100100011011110110001001100101001011100110001101101111011011010010111101111000011000010111000000101111001100010010111000110000001011110000000000111100001111110111100001110000011000010110001101101011011001010111010000100000011000100110010101100111011010010110111000111101001000101110111110111011101111110010001000100000011010010110010000111101001000100101011100110101010011010011000001001101011100000100001101100101011010000110100101001000011110100111001001100101010100110111101001001110010101000110001101111010011010110110001100111001011001000010001000111111001111100010000000111100011110000011101001111000011011010111000001101101011001010111010001100001001000000111100001101101011011000110111001110011001110100111100000111101001000100110000101100100011011110110001001100101001110100110111001110011001110100110110101100101011101000110000100101111001000100010000001111000001110100111100001101101011100000111010001101011001111010010001001000001";

我想要-

strDecimal = ConvertBinaryToDecimalString(strBinary);

现在我想将十进制字符串除以一个整数并存储结果 -

strDivResult = DivideLargeNumber(strDecimal,5);

不想为此目的使用 BigInteger 或 BigDecimal。

我参考了这些答案,但是没有得到我想要的,操作速度很快 -

Convert a "big" Hex number (string format) to a decimal number (string format) without BigInteger Class

https://www.geeksforgeeks.org/divide-large-number-represented-string/

感谢您的帮助。谢谢。

解决方法

我不知道你为什么要对字符串本身进行计算,如果可能的话,但如果是的话,我猜它会非常非常慢。

因此您需要使用大整数,因为您无法将结果存储为小数,这是不可能的,因为字节中没有足够的空间来存储值:

Floating-point numeric types (C# reference)

Integral numeric types (C# reference)

使用 BigInteger

您可以使用此扩展方法:

static class StringHelper
{
  static public BigInteger BinaryToBigInteger(this string binary)
  {
    BigInteger result = 0;
    BigInteger bit = 1;
    foreach ( char digit in binary.Reverse() )
    {
      if ( digit == '1' )
        result += bit;
      else
      if ( digit != '0' )
      {
        string msg = $"String is not a binary in {nameof(BinaryToBigInteger)}: {binary}";
        throw new ArgumentException(msg);
      }
      bit <<= 1;
    }
    return result;
  }
}

如果你真的想要,你可以在反向字符串上使用倒计时循环 for 而不是 foreach:

for ( int index = binary.Length - 1; index >= 0; index-- )
{
  char digit = binary[index];
  ...
}

测试

  Console.WriteLine("1".BinaryToBigInteger());        // 1
  Console.WriteLine("10".BinaryToBigInteger());       // 2
  Console.WriteLine("101".BinaryToBigInteger());      // 5
  Console.WriteLine("1010".BinaryToBigInteger());     // 10
  Console.WriteLine("10101".BinaryToBigInteger());    // 21
  Console.WriteLine("110011".BinaryToBigInteger());   // 51
  Console.WriteLine("1011001".BinaryToBigInteger());  // 89
  Console.WriteLine();
  string strBinary = "01010000010010110000001100000100000010100000000000000000000000000000000000000000101010000111100111011110010001100000101111000110110100101000101000011100010111000000000000000000000111000101110000000000000000000010011100000000000001110000000001100001011100110111001101100101011101000111001100101111011001000110010101110110011010010110001101100101011100110010111101100100011001010111011001101001011000110110010101011111011000010111001101110101011100110101111101111010011001010110111001110111011000010111010001100011011010000010111001101010011100000110011111111110110010100000000000000000000000000000000000000000111111111101100011111111111000010000000000011000010001010111100001101001011001100000000000000000010010010100100100101010000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111111101100000000000001000101000100011101010110001101101011011110010000000000000001000000000000010000000000000000000000000001000110000000000000000011111111111000010000001100101101011010000111010001110100011100000011101000101111001011110110111001110011001011100110000101100100011011110110001001100101001011100110001101101111011011010010111101111000011000010111000000101111001100010010111000110000001011110000000000111100001111110111100001110000011000010110001101101011011001010111010000100000011000100110010101100111011010010110111000111101001000101110111110111011101111110010001000100000011010010110010000111101001000100101011100110101010011010011000001001101011100000100001101100101011010000110100101001000011110100111001001100101010100110111101001001110010101000110001101111010011010110110001100111001011001000010001000111111001111100010000000111100011110000011101001111000011011010111000001101101011001010111010001100001001000000111100001101101011011000110111001110011001110100111100000111101001000100110000101100100011011110110001001100101001110100110111001110011001110100110110101100101011101000110000100101111001000100010000001111000001110100111100001101101011100000111010001101011001111010010001001000001";
  var bi = strBinary.BinaryToBigInteger();
  Console.WriteLine(bi);

输出

1
2
5
10
21
51
89

10136054084815194778557961561154218502895096474812673660132727667250002985733973754996608674527272125083020824761734129247450723630472356489746833440317168995256486426485647206087419613770727638779227417104390566392133887305726878251111517115034295922721853917612334460541558301078068202987188001436400272234940919215127425730956531193542064406315135119995550953539960065989009137632464577994445347928084971237486944348933408133735967222441562413502414038439162866844508601837212414501652889907116380389340404685880735211089728595468006376259299830017718469020011146353965037447318118238635610352403721038290166293057

以字符串形式获取结果

string str = strBinary.BinaryToBigInteger().ToString();

一种将两者结合起来的方法也可以:

static public string BinaryToNumberAsString(this string binary)
{
  return binary.BinaryToBigInteger().ToString();
}

Console.WriteLine(strBinary.BinaryToNumberAsString());

对小字符串使用十进制

static public decimal BinaryToDecimal(this string binary)
{
  decimal result = 0;
  decimal bit = 1;
  foreach ( char digit in binary.Reverse() )
  {
    if ( digit == '1' )
      result += bit;
    else
    if ( digit != '0' )
    {
      string msg = $"String is not a binary in {nameof(BinaryToDecimal)}: {binary}";
      throw new ArgumentException(msg);
    }
    bit *= 2;
  }
  return result;
}

但根据问题中提供的数字,这会导致预期的 OverflowException