Binary to decimal in C#
using System.Globalization;
Console.WriteLine(Convert.ToInt32("1010", 2)); // 10
Console.WriteLine(int.Parse("1010", NumberStyles.BinaryNumber)); // 10
Console.WriteLine(int.TryParse("0b1010", NumberStyles.BinaryNumber, null, out _)); // False
Console.WriteLine(Convert.ToString(10, 2)); // 1010
Console.WriteLine(10.ToString("B8")); // 00001010
Console.WriteLine(Convert.ToString(-10, 2)); // 11111111111111111111111111110110
Console.WriteLine(Convert.ToString((sbyte)-10, 2)); // 1111111111110110
Console.WriteLine(0b1010_1010); // 170
Convert.ToInt32(s, 2)works on every .NET version. The bits are a pattern: 32 ones are -1, and a 33rd significant bit is an OverflowException. It takes no0bprefix:Convert.ToInt32("0b101", 2)gives FormatException: "Additional non-parsable characters are at the end of the string."int.Parse(s, NumberStyles.BinaryNumber)and the"B"format (10.ToString("B8")) are new in .NET 8. BinaryNumber allows spaces around the bits, no prefix and no separators.BigInteger.Parse(s, NumberStyles.BinaryNumber)reads the first bit as the sign, like hex: "1" is -1 and "01" is 1. On .NET 8 it throws ArgumentException: "An undefined NumberStyles value is being used. (Parameter 'style')"; .NET 10 supports it, and BigInteger's"B"format too.- Binary literals use the literal type rule:
0b1111_1111_1111_1111_1111_1111_1111_1111is a uint (4294967295), whileConvert.ToInt32of the same 32 ones is -1.
Two's complement: why FFFFFFFF is -1
C# stores sbyte, short, int and long in two's complement: the top bit counts as minus 2n-1 instead of plus. So the 32 bits FFFFFFFF are -1 as an int and 4294967295 as a uint, and 80000000 is int.MinValue. To negate a value, invert the bits and add 1: 1 is 00000001, -1 is FFFFFFFF, -255 is FFFFFF01.
A cast between types of the same width keeps the bits and changes their meaning; a cast to a narrower type keeps the low bits. Constants need unchecked: (int)0xFFFFFFFF does not compile (error CS0221), unchecked((int)0xFFFFFFFF) is -1. Pick a width above to see both readings of the same bits.
C# integer literals and their type
An integer literal without a suffix gets the first of int, uint, long, ulong that can hold it. With u it is uint or ulong, with L long or ulong, and with UL always ulong. Hex and binary follow the same rule, which is why 0xFFFFFFFF is a uint and int x = 0xFFFFFFFF; does not compile:
Console.WriteLine((0x7FFFFFFF).GetType().Name); // Int32
Console.WriteLine((0xFFFFFFFF).GetType().Name); // UInt32
Console.WriteLine((0x1_0000_0000).GetType().Name); // Int64
Console.WriteLine((0xFFFF_FFFF_FFFF_FFFF).GetType().Name); // UInt64
Console.WriteLine((0xFFu).GetType().Name); // UInt32
Console.WriteLine((0xFFL).GetType().Name); // Int64
Console.WriteLine((-2147483648).GetType().Name); // Int32
Console.WriteLine((-2147483649).GetType().Name); // Int64
Console.WriteLine(010); // 10
- Prefixes:
0xor0Xfor hex,0bor0Bfor binary (C# 7). C# has no octal literal:010is ten. - Digit separators:
_can go between any digits, and more than one in a row:1_000_000,0b1010_1010. Right after0xor0bis fine too (0x_FF, C# 7.2), but not at the end:0xFF_is error CS1013, "Invalid number". - Suffixes:
u,l,ulorluin any case. A lowercaselfirst draws warning CS0078 because it looks like a 1; writeL. - Negative literals: the minus is an operator applied to the literal, so
-2147483648is an int only thanks to a special rule,-2147483649is a long, and-18446744073709551615is error CS0023, sinceulonghas no minus. Pastulong.MaxValuea literal is error CS1021, "Integral constant is too large"; useBigInteger.Parse.
FAQ
How do I convert binary to decimal in C#?
Convert.ToInt32(bits, 2), or Convert.ToInt64 for up to 64 bits. On .NET 8 and later int.Parse(bits, NumberStyles.BinaryNumber) does the same.
How do I convert an int to binary in C#?
Convert.ToString(value, 2), or value.ToString("B") on .NET 8 and later. "B8" or "B32" pads with zeros.
Why does 11111111 give -1?
Read as an 8-bit signed number (sbyte), the top bit is the sign in two's complement, so all ones is -1. As a byte, or in any wider type, it is 255.
Can I write binary numbers in C# code?
Yes, with the 0b prefix (C# 7): 0b1010 is 10. Use _ to group the bits: 0b1111_0000.