一个正数,按照其本身大小转换成的二进制数,称为原码
一个负数,按照其绝对值大小转换成的二进制数,最高位补1,称为原码
正数的反码与原码相同
负数的反码为对该数的原码除符号位【最高位】外各位取反(0变1,1变0,符号位为1不变)
正数的补码与原码相同
负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.即对负数的补码为对该数的反码的最后一位加1
正数的补码为本身,0的补码为0,负数的补码【将其原码除符号位外的所有位取反(0变1,1变0,符号位为1不变)后加1】,对于C#来说,使用一个强转即可。如下代码:
int x=-123;
byte twosComplement=(byte)x;
下面使用WindowsForm应用程序测试整数的二进制原码、反码、补码
负数的新建WinForms应用程序BinaryDemo,将默认的Form1重命名为FormBinary,
窗体FormBinary设计如下:
FormBinary源程序如下:
(忽略设计器自动生成的代码)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BinaryDemo
public partial class FormBinary : Form
public FormBinary()
InitializeComponent();
Dictionary<string, int> dict = new Dictionary<string, int>();
dict.Add("八位SByte", 8);
dict.Add("十六位Int16", 16);
dict.Add("三十二位Int32", 32);
cboBase.DropDownStyle = ComboBoxStyle.DropDownList;
cboBase.DataSource = dict.ToList();
cboBase.DisplayMember = "Key";
cboBase.ValueMember = "Value";
cboBase.SelectedIndex = 2;//默认选中32bits
private void FormBinary_Load(object sender, EventArgs e)
/* 计算机采用二进制补码【Complement】的格式来表示十进制整数
* 原码:
* 一个正数,按照其本身大小转换成的二进制数,称为原码
* 一个负数,按照其绝对值大小转换成的二进制数,最高位补1,称为原码
* 反码:
* 正数的反码与原码相同
* 负数的反码为对该数的原码除符号位外各位取反
* 补码:
* 正数的补码与原码相同
* 负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.即对负数的补码为对该数的反码的最后一位加1
/// <summary>
/// 验证输入
/// </summary>
/// <returns></returns>
private bool CheckInput()
if (txtSourceNumber.Text.Trim().Length == 0)
txtSourceNumber.Focus();
MessageBox.Show("源整数不能为空", "出错");
return false;
int fromBase = Convert.ToInt32(cboBase.SelectedValue);
switch (fromBase)
case 8:
if (!sbyte.TryParse(txtSourceNumber.Text, out sbyte result1))
txtSourceNumber.Focus();
MessageBox.Show("请输入[-128,127]之间的整数", "出错");
return false;
break;
case 16:
if (!short.TryParse(txtSourceNumber.Text, out short result2))
txtSourceNumber.Focus();
MessageBox.Show("请输入[-32768,32767]之间的整数", "出错");
return false;
break;
case 32:
if (!int.TryParse(txtSourceNumber.Text, out int result3))
txtSourceNumber.Focus();
MessageBox.Show($"请输入[{int.MinValue},{int.MaxValue}]之间的整数", "出错");
return false;
break;
return true;
private void btnGet_Click(object sender, EventArgs e)
if (!CheckInput())
return;
int fromBase = Convert.ToInt32(cboBase.SelectedValue);
long result = 0;
switch (fromBase)
case 8:
result = sbyte.Parse(txtSourceNumber.Text);
break;
case 16:
result = short.Parse(txtSourceNumber.Text);
break;
case 32:
result = int.Parse(txtSourceNumber.Text);
break;
txtBinary.Text = Convert.ToString((int)result, 2).PadLeft(32, '0');
DisplayBinaryWhenEightBit(txtBinary);
if (Math.Sign(result) < 0) //是否是负数
//如果是负数,先获取绝对值,然后最高位补1
switch (fromBase)
case 8:
GetNegativeOriginalBinary(fromBase, (sbyte)result);
break;
case 16:
GetNegativeOriginalBinary(fromBase, (short)result);
break;
case 32:
GetNegativeOriginalBinary(fromBase, (int)result);
break;
//GetNegativeOriginalBinary(fromBase, result);
//负数的反码为对该数的原码除符号位外各位取反
string sAnticode = "1";
for (int i = 1; i < fromBase; i++)
sAnticode += (txtOriginalBinary.Text[i] == '0' ? "1" : "0");
txtAnticodeBinary.Text = sAnticode;
//负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.即对负数的补码为对该数的反码的最后一位加1
txtComplementBinary.Text = Convert.ToString(Convert.ToInt64(sAnticode, 2) + 1, 2);
//如果是正数,最高位补零
txtOriginalBinary.Text = "0" + Convert.ToString(result, 2).PadLeft(fromBase - 1, '0');
txtAnticodeBinary.Text = txtOriginalBinary.Text;
txtComplementBinary.Text = txtOriginalBinary.Text;
txtOriginal.Text = Convert.ToInt64(txtOriginalBinary.Text, 2).ToString();
txtAnticode.Text = Convert.ToInt64(txtAnticodeBinary.Text, 2).ToString();
txtComplement.Text = Convert.ToInt64(txtComplementBinary.Text, 2).ToString();
DisplayBinaryWhenEightBit(txtOriginalBinary);
DisplayBinaryWhenEightBit(txtAnticodeBinary);
DisplayBinaryWhenEightBit(txtComplementBinary);
/// <summary>
/// 获取负数的原码
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="fromBase"></param>
/// <param name="resultText"></param>
private void GetNegativeOriginalBinary<T>(int fromBase, T resultText) where T : struct, IComparable
if (fromBase == 8)
sbyte result = (sbyte)(object)resultText;
//如果是负数,先获取绝对值,然后最高位补1
if (result == sbyte.MinValue)
byte processValue = (byte)result;//直接就是8位
txtOriginalBinary.Text = Convert.ToString(processValue, 2);
sbyte absValue = Math.Abs(result);
txtOriginalBinary.Text = "1" + Convert.ToString(absValue, 2).PadLeft(fromBase - 1, '0');
else if (fromBase == 16)
short result = (short)(object)resultText;
//如果是负数,先获取绝对值,然后最高位补1
if (result == short.MinValue)
ushort processValue = (ushort)result;//直接就是16位
txtOriginalBinary.Text = Convert.ToString(processValue, 2);
short absValue = Math.Abs(result);
txtOriginalBinary.Text = "1" + Convert.ToString(absValue, 2).PadLeft(fromBase - 1, '0');
else if (fromBase == 32)
int result = (int)(object)resultText;
//如果是负数,先获取绝对值,然后最高位补1
if (result == int.MinValue)
uint processValue = (uint)result;//直接就是32位
txtOriginalBinary.Text = Convert.ToString(processValue, 2);
int absValue = Math.Abs(result);
txtOriginalBinary.Text = "1" + Convert.ToString(absValue, 2).PadLeft(fromBase - 1, '0');
/// <summary>
/// 将文本框的二进制字符串每隔8位就使用空格 间隔开
/// </summary>
/// <param name="textBox"></param>
private void DisplayBinaryWhenEightBit(TextBox textBox)
int pageSize = (textBox.Text.Length + 7) / 8;
string[] splitArray = new string[pageSize];
for (int i = 0; i < pageSize; i++)
if (i + 1 == pageSize)
splitArray[i] = textBox.Text.Substring(8 * i);
splitArray[i] = textBox.Text.Substring(8 * i, 8);
//使用空格拼接
textBox.Text = string.Join("\x20\u0020", splitArray);
程序运行如图:
计算机采用二进制补码【Complement】的格式来表示十进制整数,无论正整数、0、负整数都是采用二进制补码的方式来存储数据。基本概念原码: 一个正数,按照其本身大小转换成的二进制数,称为原码 一个负数,按照其绝对值大小转换成的二进制数,最高位补1,称为原码反码: 正数的反码与原码相同 负数的反码为对该数的原码除符号位【最高位】外各位取反(0变1,1变0,符号位为1不变)补码: 正数的补码与原码相同 负数的补码为对该数的原码除符号位外各位取反,然
原码:将最高位作为符号位(0表示正,1表示负),其它数字位代表数值本身的绝对值的数字表示方式。
反码:如果是正数,则表示方法和原码一样;如果是负数,符号位不变,其余各位取反,则得到这个数字的反码表示形式。
补码:如果是正数,则表示方法和原码一样;如果是负数,则将数字的反码加上1(相当于将原码数值位取反然后在最低位加1)。
总结:正数的原码、反码、补码完全一样,只有负数需要按照以上规则计算。
把一个数用二进制形式表示,如果是正数,原码就等于其二进制数,如果是负数,最高位,也就是最左边的那一位变成1
把一个数表示成二进制的时候注意,一定要比正常表示的二进制多4位,用来标记是正数还是负数
比如:12可以表示成1100,但是写的时候要比它多四位,也就是 0000 1100,最高位为0,表示为正,如果是-12,就是1000 1100
25可以表示成0001...
按位取反就是对数据的每个二进制位取反,即把0变成1,把1变成0。
例如二进制"00001111",取反操作得到"11110000"。
由此,我们可以通过位取反操作实现一个简单的自动加解密程序。
加密时将每一个字节进行位取反操作,解密也进行同样操作,就能得出原数据。
C# 通过按位取反实现简单自动加解密
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
二进制原码表示法是指符号位加上数值位,其中符号位 0 表示正数,1 表示负数。数值位用二进制表示数字的大小。
二进制补码表示法是将一个二进制数的原码取反(即将每一位都取反),再加 1。例如,原码为 1001,则补码为 0110。
二进制反码表示法是将一个二进制数的原码取反,但不加 1。例如,原码为 1001,则反码为 0110。