Binary NOT in c#

Keeponfalling 41 Reputation points
2020-12-01T21:47:53.403+00:00

Hello
I have a misunderstanding issue...if you can please help me.
I get a binary number: 110 for example, in string format and I want to apply the not ~ operator and get 001.

I try to convert it to sbyte or byte but for "1" I get 49. Also, I convert it to int and apply the ~ and get a different result, not what I looking for and I don't understand why.
Can you give me some suggestions, please. Thanks.

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,363 questions
{count} votes

Accepted answer
  1. Andrea Angella 171 Reputation points MVP
    2020-12-01T22:51:20.493+00:00

    The Convert class can help you to convert binary numbers between the string and integer types.

    Convert.ToInt32(input, 2) helps you to take your binary number as a string and convert it into an integer
    Convert.ToString(n, 2) helps you to convert an integer into its binary representation as a string

    The tricky part is that ToString prints all the binary digits in the number (32 bits) so if you only want to consider 3 digits you need to only take the last 3 from the string generated.

    string BinaryNot(string input)           // 110  
    {                                           
        var n = Convert.ToInt32(input, 2);   // 6  
        var notN = Convert.ToString(~n, 2);  // 11111111111111111111111111111001  
        return notN[^input.Length..];        // 001  
    }  
    

    In this case, however, using a simple string manipulation and invert 0s with 1s is easier and more compact.

    string BinaryNot(string input) => string.Concat(input.Select(x => x == '0' ? '1' : '0'));  
    
    1 person found this answer helpful.
    0 comments No comments

6 additional answers

Sort by: Most helpful
  1. WayneAKing 4,921 Reputation points
    2020-12-02T00:30:01.657+00:00

    I get a binary number: 110 for example, in string format and I want
    to apply the not ~ operator and get 001.

    First off, in C# the tilde is called the "Bitwise complement operator ~".

    If you really must use the ~ operator, play with this example:

    string str1 = "110";
    string str2 = "";
    for (int n = 0; n < str1.Length; ++n)
    {
        byte x = (byte)(str1[n] - '0');
        byte y = (byte)((~x) & 0x01);
        str2 += y;
    }          
    
    • Wayne
    1 person found this answer helpful.

  2. Cheong00 3,471 Reputation points
    2020-12-02T01:48:49.34+00:00

    When you use "~" operator, the value is implicitly converted to int/uint before the operation and then assigning back to the variable

    sbyte n = 3;
    n = ~n;
    Console.WriteLine(n);

    Compilation error (line 8, col 7): Cannot implicitly convert type 'int' to 'sbyte'. An explicit conversion exists (are you missing a cast?)

    On the other hand, if you change it to "uint n = 3;", it will run correctly with result 4294967292.

    So my recommandation would be to use uint all the time, then use "& 0x000000FF" to mask out the leftmost 24 bits from it.

    uint n = 3;
    n = ~n;
    Console.WriteLine("{0:X}", n & 0x000000FF); //shows "FC"

    1 person found this answer helpful.
    0 comments No comments

  3. WayneAKing 4,921 Reputation points
    2020-12-02T20:47:38.507+00:00

    Can you please explain me what happens here, after AND - (byte)((~x) & 0x01) -
    And here: str1[n] - '0') (do you get the byte value 1 instead of 49?)

    Yes. As I described in an earlier comment, the character '0' has a value
    of 0x30 or dec 48. So in that code I am subtracting the value of the
    character '0' from the numeric character that is in the string. So if
    the character from the string is a '0' (dec 48) the code subtracts dec 48
    from it leaving the numeric value of 0. If the character from the string
    is a '1' (dec 49) the code subtracts '0' (dec 48) from it leaving the
    numeric value 1.

    It is a shorthand way of converting a number character to its numeric
    equivalent. So '0' becomes 0 and '1' becomes 1.

    what happens here, after AND - (byte)((~x) & 0x01)

    The bitwise AND (&) yields the conjunction (or binary product) of the
    two values. The result will have bits set wherever they exist in both
    values only.

    Since the only bit set in the mask 0x01 is the lowest (least significant)
    bit then that is the only bit that can be set in the result.

    If the value being ANDed with the mask has the least significant bit
    set then the result will also have that (and only that) bit set. Otherwise
    the result will have no bits set. Using 0x01 strips off all bits from the
    value in ~x except for the last (least) bit, which may or not be set .

    • Wayne
    1 person found this answer helpful.

  4. WayneAKing 4,921 Reputation points
    2020-12-08T17:20:35.923+00:00

    Is there a way to apply shift left or shift right only by changing
    the ~ operator?

    What do you mean by "changing the ~ operator"?

    Do you mean overloading the operator for your own class to do something
    different than the normal default behaviour of that operator?

    Or do you mean changing the code to eliminate the ~ operator altogether?

    It's not clear exactly what you're trying to do with bit shifts.

    If you just want to replace the bitwise AND (&) with bit shifting then
    this is one way:

    string str1 = "11001110011";
    string str2 = "";
    for (int n = 0; n < str1.Length; ++n)
    {
        byte x = (byte)(str1[n] - '0');
        byte y = (byte)((uint)((~x)<<31)>>31);
        str2 += y;
    }
    

    Is ok if I change: (byte)((x) ^ (y))

    It's OK by me, but I don't know what you expect it to do.
    So it may not be OK for accomplishing what you want.

    The best way to get an answer to your questions such as
    "Is it OK?" or "Will it work?" is to try the code and
    analyze the result.

    • Wayne
    1 person found this answer helpful.