简体   繁体   中英

Convert.ToString() to binary format not working as expected

int i = 20;
string output = Convert.ToString(i, 2); // Base2 formatting
i = -20;
output = Convert.ToString(i, 2);
Value   Expected                            Actual
20      00000000000000000000000000010100    10100
-20     10000000000000000000000000010100    11111111111111111111111111101100

I can see that perhaps the binary output of 20 has been truncated but I do not understand the output for -20. I based my expectations on base2 notation plus a belief that the signed element of an integer was expressed in the first left most digit. 0 for positive and 1 for negative. Can someone explain the results, specifically that of -20?

Negative numbers in .NET are represented in binary as Two's complement .

From MSDN - Convert.ToString Method (Int32, Int32) :

If value is negative and toBase is 2, 8, or 16, the returned string uses two's complement representation

for integer -20 is 11111111111111111111111111101100 System is using 2's Complement by default. 1's Complement is not ideal for calculation.

(2's complement is invert of all bit plus one)

in 2's Complement, which will make 20 + (-20) = 0, can compute math easily without concern positive or negative.

for example, in signed char: 15 = 00001111, -18 = 2's Complement of (00010010) = 11101101 + 1 = 11101110

00001111 +11101110 =11111101

Since first bit is 1, we know it is a negative value. Let's do a reverse 2's Complement.

11111101 - 1 = 11111100 => -(00000011) it gives -3 which 15 + (-18) = -3

int value = 31;
string binary = Convert.ToString(value, 2);
Console.WriteLine(binary.PadLeft(8, '0'));          // Outputs "00011111"

This is basically the same answer as everyone else has posted, just packaged in a method.

  /// <summary>
  /// Method to convert an integer to a string containing the number in binary. A negative 
  /// number will be formatted as a 32-character binary number in two's compliment.
  /// </summary>
  /// <param name="theNumber">self-explanatory</param>
  /// <param name="minimumDigits">if binary number contains fewer characters leading zeros are added</param>
  /// <returns>string as described above</returns>
  public static string IntegerToBinaryString(int theNumber, int minimumDigits)
  {
     return Convert.ToString(theNumber, 2).PadLeft(minimumDigits, '0');
  }

This function does exactly what you want

string ConvertToFuzzyFrogBinary(int input)
{
    int prefix = (input).ToString("d8").Length-(Math.Abs((input))).ToString("d8").Length;
    string binary_num = "00000000000000000000000000000000".Substring(0,32-Convert.ToString(Math.Abs(input),2).Length)+Convert.ToString(Math.Abs(input),2);
    return "1".Substring(0,prefix)+binary_num.Substring(prefix,32-prefix);
}

Here is a routine I wrote that does what the original questioner wanted. A mere 5 years too late!

/// <summary>Convert a number into a string of bits</summary>
/// <param name="value">Value to convert</param>
/// <param name="minBits">Minimum number of bits, usually a multiple of 4</param>
/// <exception cref="InvalidCastException">Value must be convertible to long</exception>
/// <exception cref="OverflowException">Value must be convertible to long</exception>
/// <returns></returns>
public static string ShowBits<T>(this T value, int minBits)
{
    long x = Convert.ToInt64(value);
    string retVal = Convert.ToString(x, 2);
    if (retVal.Length > minBits) retVal = Regex.Replace(retVal, @"^1+", "1");   // Replace leading 1s with a single 1 - can pad as needed below
    if (retVal.Length < minBits) retVal = new string(x < 0 ? '1' : '0', minBits - retVal.Length) + retVal;  // Pad on left with 0/1 as appropriate
    return retVal;
}

If you would get rid of this "effect" - use Math.Abs() method to get number value without sign,

string output = Convert.ToString(Math.Abs(i), 2); // Base2 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM