C#中的整数的二进制原码、反码、补码

计算机采用二进制补码【Complement】的格式来表示十进制整数,无论正整数、0、负整数都是采用二进制补码的方式来存储数据。

基本概念

原码:

    一个正数,按照其本身大小转换成的二进制数,称为原码
    一个负数,按照其绝对值大小转换成的二进制数,最高位补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);
            }
            else
            {
                //如果是正数,最高位补零
                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);
                }
                else
                {
                    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);
                }
                else
                {
                    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);
                }
                else
                {
                    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);
                }
                else
                {
                    splitArray[i] = textBox.Text.Substring(8 * i, 8);
                }
            }
            //使用空格拼接
            textBox.Text = string.Join("\x20\u0020", splitArray);
        }
    }
}

程序运行如图:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯内科

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值