编程基础 - 进制转换(Binary Conversion)

本文介绍了编程基础中的进制转换,包括从其他进制转十进制、十进制转其他进制的方法,强调了二进制与其他乘方进制之间的快速转换。此外,还讲解了位运算的基础概念,如位与、位或、位取反和位异或,并提供了C#和C++的代码示例。

编程基础 - 进制转换(Binary Conversion)



1 进制(System of Numeration)

进制(进位计数法) 是一种人为定义带进位的计数方法。对于任何一种进制,都是每个位置上的数达到“几”进一。而这个“几”就是人为定义的,称做 基数(底数) 。比如现在最常用的十进制就是人为定义“几”为十,即每一位可用的数为十个(0,1,2,3,4,5,6,7,8,9)。关于进制更详细的解释还请自行搜索。

最常用的进制为:十进制,二进制,十六进制,八进制。

根据概念我们每一位可用的数字如下表:

进制每一位能够使用的数字表示
十进制(DEC)0,1,2,3,4,5,6,7,8,9
二进制(BIN)0,1
十六进制(HEX)0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
八进制(OCT)0,1,2,3,4,5,6,7

2 其它进制转十进制(Others to DEC)

每一位的运算为基数的位置次方乘以数字表示(注意,位置是从0开始计算,而非1),每一位的运算结果之和表示这个数。

举例来说十进制数字129即:

  • 十进制: 129 = 10 2 × 1 + 10 1 × 2 + 10 0 × 9 129 = {10}^2 \times 1 + {10}^1 \times 2 + {10}^0 \times 9 129=102×1+101×2+100×9

  • 二进制: 10000001 = 10 1110 × 1 + 10 1101 × 0 + ⋯ + 10 1 × 0 + 10 0 × 1 1000 0001 = {10}^{1110} \times 1 + {10}^{1101} \times 0 + \cdots + {10}^1 \times 0 + {10}^0 \times 1 10000001=101110×1+101101×0++101×0+100×1

  • 十六进制: 81 = 10 1 × 8 + 10 0 × 1 81 = {10}^1 \times 8 + {10}^0 \times 1 81=101×8+100×1

  • 八进制: 201 = 10 2 × 2 + 10 1 × 0 + 10 0 × 1 201 = {10}^2 \times 2 + {10}^1 \times 0 + {10}^0 \times 1 201=102×2+101×0+100×1

你会看到基数全部都是10,但它们是不同的,它们表示的是对应进制的10,而不是十进制的10。

如果全部换成十进制的表示就是:

  • 十进制: 129 = 10 2 × 1 + 10 1 × 2 + 10 0 × 9 = 129 129 = {10}^2 \times 1 + {10}^1 \times 2 + {10}^0 \times 9 = 129 129=102×1+101×2+100×9=129

  • 二进制: b 10000001 = 2 7 × 1 + 2 6 × 0 + ⋯ + 2 1 × 0 + 2 0 × 1 = 129 b1000 0001 = {2}^7 \times 1 + {2}^6 \times 0 + \cdots + {2}^1 \times 0 + {2}^0 \times 1 = 129 b10000001=27×1+26×0++21×0+20×1=129

  • 十六进制: x 81 = 16 1 × 8 + 16 0 × 1 = 129 x81 = {16}^1 \times 8 + {16}^0 \times 1 = 129 x81=161×8+160×1=129

  • 八进制: o 201 = 8 2 × 2 + 8 1 × 0 + 8 0 × 1 + = 129 o201 = {8}^2 \times 2 + {8}^1 \times 0 + {8}^0 \times 1 + = 129 o201=82×2+81×0+80×1+=129

其它进制也同理。


3 十进制转换其它进制(DEC to Others)

十进制转换成其它进制使用了求余数的方法,按位填充(从右向左)。

例如,十进制数字96783:

  • 十六进制运算过程:

    96783 ÷ 16 = 6048 ⋯ 15 → x F 6048 ÷ 16 = 378 ⋯ 0 → x 0 378 ÷ 16 = 23 ⋯ 10 → x A 23 ÷ 16 = 1 ⋯ 7 → x 7 1 ÷ 16 = 0 ⋯ 1 → x 1 \begin{aligned} 96783 \div 16 &= 6048 \cdots 15 &\rightarrow xF \\ 6048 \div 16 &= 378 \cdots 0 &\rightarrow x0 \\ 378 \div 16 &= 23 \cdots 10 &\rightarrow xA \\ 23 \div 16 &= 1 \cdots 7 &\rightarrow x7 \\ 1 \div 16 &= 0 \cdots 1 &\rightarrow x1 \end{aligned} 96783÷166048÷16378÷1623÷161÷16=604815=3780=2310=17=01xFx0xAx7x1

    即最终结果为:x 17A0F

  • 二进制运算过程:

    96783 ÷ 2 = 48391 ⋯ 1 → b 1 48391 ÷ 2 = 24195 ⋯ 1 → b 1 ⋮ 5 ÷ 2 = 2 ⋯ 1 → b 1 2 ÷ 2 = 1 ⋯ 0 → b 0 1 ÷ 2 = 0 ⋯ 1 → b 1 \begin{aligned} 96783 \div 2 &= 48391 \cdots 1 &\rightarrow b1 \\ 48391 \div 2 &= 24195 \cdots 1 &\rightarrow b1 \\ \vdots \\ 5 \div 2 &= 2 \cdots 1 &\rightarrow b1\\ 2 \div 2 &= 1 \cdots 0 &\rightarrow b0\\ 1 \div 2 &= 0 \cdots 1 &\rightarrow b1 \end{aligned} 96783÷248391÷25÷22÷21÷2=483911=241951=21=10=01b1b1b1b0b1

    即最终结果为(不够4位补0):b 0001 0111 1010 0000 1111

  • 八进制为 o 275017

  • 其它进制同理。


4 二进制与其乘方进制(BIN and Power N)

在前面,我们看到二进制的计算是用2的次方计算。这样就造成了一个现象,二可以与乘方进制更快速的进行计算。

比如二进制与十六进制在计算机语言中是常用的,这是因为每4位的二进制数可表示为1位的十六进制数。这样只要记住4位二进制与1位十六进制对应关系,就不需要额外计算。同理其它进制也是这样。

如下表:

100123456789101112131415
201101110010111011110001001101010111100110111101111
40123101112132021222330313233
8012345671011121314151617
160123456789ABCDEF

你会发现一个很有意思的现象:

  • 二进制:2为2的1次方,则每1位表示一个数;

  • 四进制:4为2的2次方,则每2位表示一个数;

  • 八进制:8为2的3次方,则每3位表示一个数;

  • 十六进制:16为2的4次方,则每4位表示一个数。

以此类推,三十二进制(0-W)即每5位表示一个数等等, 过高的进制还不如转换成十进制再转换回来,因为记不住这么多对应关系。

来练习一下计算,你可以拿计算器验证结果:

  • 4进制 3123(219) : 3(11),1(01),2(10),3(11) 即 b 1101 1011

  • o 6372(3322) : 6(110),3(011),7(111),2(010) 即 b 1100 1111 1010

  • x BC2F(48175) : B(1011),C(1100),2(0010),F(1111) 即 b 1011 1100 0010 1111

  • 32进制 G2K1(526977) : G(10000),2(00010),K(10100),1(00001) 即 b 1000 0000 1010 1000 0001

那么可以看出,它们之间的转换,用二进制作为中介要比十进制要好一些(因人而异)。

类似的,四进制与十六进制也可以进行转换(16为4的2次方,即每2位表示一个数),例如刚才举例的 x BC2F : B(23),C(30),2(02),F(33) 即四进制 23300233


5 位运算(Bitwise)

位运算算是计算机语言中最常用的方式二进制方式。

位的基本运算包括:位与(&)、位或(|)、位取反(~)、位异或(^)。当然还包含其它,例如移位,但我们暂时不用知道移位运算。

  • 位与(&)即是每一位进行与(and)操作,就像逻辑运算一样(1=真,0=假),左值和右值同时为1时结果为1;

  • 位或(|)即是每一位进行或(or)操作,左值和右值有一个为1时结果就为1;

  • 位取反(~)即是每一位进行非(not)操作,1变0,0变1;

  • 位异或(^)即是每一位进行异或(xor)操作,左值与右值不同时结果为1。

举个例子:

byte&|~^
Left0001 01000001 01000001 01000001 0100
Right1000 11011000 11011000 1101
Result0000 01001001 11011110 10111001 1001

6 C#完整代码(C# Full Code)

进制转换:

using System;
using System.Collections.Generic;
using System.Numerics;

namespace NumerationSystem
{
    /// <summary>
    /// 编程基础 - 进制转换(Binary Conversion)
    /// 带字母的进制,注意有大小写之分。
    /// </summary>
    public static class NumerationConversion
    {
        private readonly static Dictionary<char, uint> s_CharToUInt32;
        private readonly static Dictionary<uint, char> s_UInt32ToChar;

        public const uint k_MinNumeration = 2;
        public const uint k_MaxNumeration = 62;

        /// <summary>
        /// 静态构造
        /// </summary>
        static NumerationConversion()
        {
            // 初始化 int32 - 10进制以上字母 双向映射字典
            s_CharToUInt32 = new Dictionary<char, uint>();
            s_UInt32ToChar = new Dictionary<uint, char>();

            // 数字 0 - 9
            for (uint c = '0', i = 0; c <= '9'; c++, i++)
            {
                s_CharToUInt32[(char)c] = i;
                s_UInt32ToChar[i] = (char)c;
            }

            // 小写字母 10 - 35
            for (uint c = 'a', i = 10; c <= 'z'; c++, i++)
            {
                s_CharToUInt32[(char)c] = i;
                s_UInt32ToChar[i] = (char)c;
            }

            // 大写字母字母 36 - 61
            for (uint c = 'A', i = 36; c <= 'Z'; c++, i++)
            {
                s_CharToUInt32[(char)c] = i;
                s_UInt32ToChar[i] = (char)c;
            }
        }

        /// <summary>
        /// 第2节内容:其它进制 转 10进制
        /// </summary>
        /// <param name="value"></param>
        /// <param name="numeration"></param>
        /// <param name="error"></param>
        /// <returns></returns>
        public static BigInteger ConvertOtherToTen(string value, uint numeration, out string error)
        {
            error = string.Empty;
            // 必须比2大,比62小,62 = 10(数字) + 26(小写字母) + 26(大写字母)
            if (numeration < k_MinNumeration || numeration > k_MaxNumeration)
            {
                error = $"`numeration` must be [{k_MinNumeration}, {k_MaxNumeration}] ";
                return 0;
            }

            BigInteger result = new BigInteger();

            try
            {
                for (int i = value.Length - 1, p = 0; i >= 0; i--, p++)
                {
                    result += BigInteger.Pow(numeration, p) * s_CharToUInt32[value[i]];
                }
            }
            catch (Exception e)
            {
                error = e.ToString();
            }

            return result;
        }

        /// <summary>
        /// 第3节内容:10进制 转 其它进制
        /// </summary>
        /// <param name="value"></param>
        /// <param name="numeration"></param>
        public static string ConvertTenToOther(int value, uint numeration)
        {
            // 必须比2大,比62小,62 = 10(数字) + 26(小写字母) + 26(大写字母)
            if (numeration < k_MinNumeration || numeration > k_MaxNumeration)
            {
                return $"`numeration` must be [{k_MinNumeration}, {k_MaxNumeration}] ";
            }

            if (value == 0)
            {
                return "0";
            }

            if (numeration == 10)
            {
                return value.ToString();
            }

            uint quotient, remainder;
            string result = string.Empty;

            // 负数需要用到补码
            quotient = value < 0 ? (uint)(uint.MaxValue + value + 1) : (uint)value;
            while (quotient != 0)
            {
                remainder = quotient % numeration;
                result = s_UInt32ToChar[remainder] + result;
                quotient /= numeration;
            }

            return result;
        }
    }
}

主函数:

using System;
using System.Collections.Generic;
using System.Numerics;
using System.Text;

namespace NumerationSystem
{
    class Program
    {
        static void Main(string[] args)
        {
            // 1
            Section1();

            // 2
            Section2();

            // 3
            Section3();

            // 4
            Section4();

            // 5
            Section5();

            // 测试大数
            string bigNumString = "ZZZUIYFA436592915SUI4H234FK443HASF";
            BigInteger bigNum = NumerationConversion.ConvertOtherToTen(bigNumString, 62, out string error);
            if (string.IsNullOrEmpty(error))
            {
                Console.WriteLine("62: {0} = {1}", bigNumString, bigNum.ToString());
            }
            else
            {
                Console.WriteLine(error);
            }

            Console.ReadKey();
        }

        /// <summary>
        /// 第1节内容:进制(System of Numeration)
        /// </summary>
        private static void Section1()
        {
            Console.WriteLine("Section1: System of Numeration");

            // 2,8,16 的转换内置函数
            int num2Int32 = Convert.ToInt32("1100", 2);
            int num8Int32 = Convert.ToInt32("763", 8);
            int num16Int32 = Convert.ToInt32("fffe", 16);
            string num2String = Convert.ToString(num2Int32, 2);
            string num8String = Convert.ToString(num8Int32, 8);
            string num16String = Convert.ToString(num16Int32, 16);

            // 2 16 的赋值内置函数
            int num2Int32Equal = 0b1100; // C# 7.0+
            int num16Int32Equal = 0xfffe;

            Console.WriteLine("\t Built-in function:");
            Console.WriteLine($"\t Convert.ToInt32({"1100"}, 2) = {num2Int32}");
            Console.WriteLine($"\t Convert.ToInt32({"763"}, 8) = {num8Int32}");
            Console.WriteLine($"\t Convert.ToInt32({"fffe"}, 16) = {num16Int32}");
            Console.WriteLine($"\t Convert.ToString({num2Int32}, 2) = {PrettyNum2(num2String)}");
            Console.WriteLine($"\t Convert.ToString({num8Int32}, 8) = {num8String}");
            Console.WriteLine($"\t Convert.ToString({num16Int32}, 16) = {num16String}");
            Console.WriteLine($"\t int num2Int32Equal = 0b1100; -> num2Int32Equal is {num2Int32Equal}");
            Console.WriteLine($"\t int num2Int32Equal = 0xfffe; -> num16Int32Equal is {num16Int32Equal}");

            Console.WriteLine();
        }

        /// <summary>
        /// 第2节内容:其它进制 转 10进制
        /// </summary>
        private static void Section2()
        {
            Console.WriteLine("Section2: Others to DEC");

            string num2 = "10000001";
            string num16 = "81";
            string num8 = "201";

            BigInteger result2 = NumerationConversion.ConvertOtherToTen(num2, 2, out string error);
            BigInteger result16 = NumerationConversion.ConvertOtherToTen(num16, 16, out error);
            BigInteger result8 = NumerationConversion.ConvertOtherToTen(num8, 8, out error);

            Console.WriteLine("\t b {0} -> {1}", PrettyNum2(num2), result2.ToString());
            Console.WriteLine("\t x {0} -> {1}", num16, result16.ToString());
            Console.WriteLine("\t o {0} -> {1}", num8, result8.ToString());

            Console.WriteLine();
        }

        /// <summary>
        /// 第3节内容:10进制 转 其它进制
        /// </summary>
        private static void Section3()
        {
            Console.WriteLine("Section3: DEC to others");

            int num10 = 96783;

            string num16 = NumerationConversion.ConvertTenToOther(num10, 16);
            string num2 = NumerationConversion.ConvertTenToOther(num10, 2);
            string num8 = NumerationConversion.ConvertTenToOther(num10, 8);

            Console.WriteLine("\t {0} -> x {1}", num10.ToString(), num16);
            Console.WriteLine("\t {0} -> b {1}", num10.ToString(), PrettyNum2(num2));
            Console.WriteLine("\t {0} -> o {1}", num10.ToString(), num8);

            Console.WriteLine();
        }

        /// <summary>
        /// 第4节内容:二进制与其乘方进制(BIN and Power N)
        /// </summary>
        private static void Section4()
        {
            Console.WriteLine("Section4: BIN and Power N");

            // 我们的方法有大小写之分
            Dictionary<uint, string> nums = new Dictionary<uint, string>
            {
                [4] = "3123",
                [8] = "6372",
                [16] = "bc2f",
                [32] = "g2k1"
            };

            Dictionary<uint, string> results = new Dictionary<uint, string>();
            string error = null;
            foreach (var kvp in nums)
            {
                BigInteger result = NumerationConversion.ConvertOtherToTen(kvp.Value, kvp.Key, out error);
                if (string.IsNullOrEmpty(error))
                {
                    results[kvp.Key] = NumerationConversion.ConvertTenToOther((int)result, 2);
                }
                else
                {
                    Console.WriteLine("ERROR: " + error);
                    return;
                }
            }

            foreach (var key in nums.Keys)
            {
                Console.WriteLine("\t {0}: {1} -> b {2}",
                    key.ToString().PadLeft(2, ' '),
                    nums[key],
                    PrettyNum2(results[key], n: (int)Math.Log(key, 2)));
            }

            Console.WriteLine();
        }

        /// <summary>
        /// 第5节:位运算例子
        /// </summary>
        private static void Section5()
        {
            Console.WriteLine("Section5: Bitwise");

            string bin1 = "00010100";
            string bin2 = "10001101";
            byte value1 = Convert.ToByte(bin1, 2);
            byte value2 = Convert.ToByte(bin2, 2);

            Console.WriteLine("\t {0} & {1} = {2}",
                bin1,
                bin2,
                Convert.ToString(value1 & value2, 2).PadLeft(8, '0'));
            Console.WriteLine("\t {0} | {1} = {2}",
                bin1,
                bin2,
                Convert.ToString(value1 | value2, 2).PadLeft(8, '0'));
            string notValue = Convert.ToString(~value1, 2).PadLeft(8, '0');
            Console.WriteLine("\t {0}  ~{1} = {2}",
                "".PadLeft(8, ' '),
                bin1,
                notValue.Substring(notValue.Length - 8));
            Console.WriteLine("\t {0} ^ {1} = {2}",
                bin1,
                bin2,
                Convert.ToString(value1 ^ value2, 2).PadLeft(8, '0'));

            Console.WriteLine();
        }

        /// <summary>
        /// 二进制左侧补0
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private static string PadLeft2(string value)
        {
            if (value == null)
            {
                value = string.Empty;
            }
            while (value.Length % 4 != 0)
            {
                value = "0" + value;
            }

            return value;
        }

        /// <summary>
        /// 每n个字符加一个空格
        /// </summary>
        /// <param name="num2"></param>
        /// <returns></returns>
        private static string PrettyNum2(string num2, int n = 4)
        {
            num2 = PadLeft2(num2);

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < num2.Length; i++)
            {
                sb.Append(num2[i]);
                if ((i + 1) % n == 0)
                {
                    sb.Append(" ");
                }
            }

            return sb.ToString().TrimEnd();
        }
    }
}

输出结果:

Section1: System of Numeration
         Built-in function:
         Convert.ToInt32(1100, 2) = 12
         Convert.ToInt32(763, 8) = 499
         Convert.ToInt32(fffe, 16) = 65534
         Convert.ToString(12, 2) = 1100
         Convert.ToString(499, 8) = 763
         Convert.ToString(65534, 16) = fffe
         int num2Int32Equal = 0b1100; -> num2Int32Equal is 12
         int num2Int32Equal = 0xfffe; -> num16Int32Equal is 65534

Section2: Others to DEC
         b 1000 0001 -> 129
         x 81 -> 129
         o 201 -> 129

Section3: DEC to others
         96783 -> x 17a0f
         96783 -> b 0001 0111 1010 0000 1111
         96783 -> o 275017

Section4: BIN and Power N
          4: 3123 -> b 11 01 10 11
          8: 6372 -> b 110 011 111 010
         16: bc2f -> b 1011 1100 0010 1111
         32: g2k1 -> b 10000 00010 10100 00001

Section5: Bitwise
         00010100 & 10001101 = 00000100
         00010100 | 10001101 = 10011101
                   ~00010100 = 11101011
         00010100 ^ 10001101 = 10011001

62: ZZZUIYFA436592915SUI4H234FK443HASF = 8736093789581089718383035241569436090815269445799968585209893


7 C++完整代码(C++ Full Code)

  • pch.h

    #ifndef PCH_H
    #define PCH_H
    
    #include <map>
    #include <string>
    #include <math.h>
    #include <limits>>
    #include <bitset>
    #include <iostream>
    
    #include "NumerationConversion.h"
    
    #endif //PCH_H
    
  • NumerationConversion.h

    #pragma once
    
    #include "pch.h"
    
    namespace NumerationSystem
    {
    
        static bool s_Init = false;
    
        /// <summary>
        /// 编程基础 - 进制转换(Binary Conversion)
        /// 带字母的进制,注意有大小写之分。
        /// </summary>
        static class NumerationConversion
        {
            // Static Field
            private:
            static std::map<char, long> s_CharToInt32;
            static std::map<long, char> s_Int32ToChar;
    
            // Const Field
            public:
            static const unsigned k_MinNumeration = 2;
            static const unsigned k_MaxNumeration = 62;
    
            // public Method
            public:
    
            // 第2节内容:其它进制 转 10进制
            static long long ConvertOtherToTen(std::string value, unsigned numeration);
    
            // 第3节内容:10进制 转 其它进制
            static std::string ConvertTenToOther(int value, unsigned numeration);
    
            // private Method
            private:
            static void InitNumerationMap();
        };
    
        // 初始化双向映射字典
        inline void NumerationConversion::InitNumerationMap()
        {
            if (s_Init)
            {
                return;
            }
    
            // 数字 0 - 9
            for (int i = 0; i < 10; i++)
            {
                NumerationConversion::s_CharToInt32[i + '0'] = i;
                NumerationConversion::s_Int32ToChar[i] = i + '0';
            }
    
            // 小写字母 10 - 35
            for (char c = 'a', i = 10; c <= 'z'; c++, i++)
            {
                NumerationConversion::s_CharToInt32[c] = i;
                NumerationConversion::s_Int32ToChar[i] = c;
            }
    
            // 大写字母 36 - 61
            for (char c = 'A', i = 36; c <= 'Z'; c++, i++)
            {
                NumerationConversion::s_CharToInt32[c] = i;
                NumerationConversion::s_Int32ToChar[i] = c;
            }
    
            s_Init = true;
        }
    }
    
  • NumerationConversion.cpp

    #include "pch.h"
    
    namespace NumerationSystem
    {
        std::map<char, long> NumerationConversion::s_CharToInt32;
        std::map<long, char> NumerationConversion::s_Int32ToChar;
    
        // 第2节内容:其它进制 转 10进制
        long long NumerationConversion::ConvertOtherToTen(std::string value, unsigned numeration)
        {
    
            if (numeration < k_MinNumeration || numeration > k_MaxNumeration)
            {
                return 0;
            }
    
            InitNumerationMap();
    
            long long result = 0;
    
            try
            {
                int p = 0;
                for (std::string::reverse_iterator rit = value.rbegin(); rit != value.rend(); rit++)
                {
                    result += (long long)powl(numeration, p) * s_CharToInt32[*rit];
                    p++;
                }
            }
            catch (const std::exception&)
            {
                return 0;
            }
    
            return result;
        }
    
        // 第3节内容:10进制 转 其它进制
        std::string NumerationConversion::ConvertTenToOther(int value, unsigned numeration)
        {
            if (numeration < k_MinNumeration || numeration > k_MaxNumeration)
            {
                return "`numeration` must be [" + std::to_string(k_MinNumeration) 
                    + ", " + std::to_string(k_MaxNumeration) + "]";
            }
    
            InitNumerationMap();
    
            if (value == 0)
            {
                return "0";
            }
    
            if (numeration == 10)
            {
                return std::to_string(value);
            }
    
            long quotient, remainder;
            std::string result = "";
    
            // 负数需要用到补码
            quotient = value < 0 ? std::numeric_limits<unsigned>::max() + value + 1 : value;
            while (quotient != 0)
            {
                remainder = quotient % numeration;
                result = s_Int32ToChar[remainder] + result;
                quotient /= numeration;
            }
    
            return result;
        }
    
    }
    
  • Program.cpp

    // NumerationSystem.cpp : This file contains the 'main' function. 
    // Program execution begins and ends there.
    
    #include "pch.h"
    
    using namespace NumerationSystem;
    
    static std::string PadLeft2(std::string value, int n = 4);
    static std::string PrettyNum2(std::string num2, int n = 4);
    void Section1();
    void Section2();
    void Section3();
    void Section4();
    void Section5();
    
    int main()
    {
        std::cout << "C++ Numeration Conversion" << std::endl;
    
        // 1
        Section1();
    
        // 2
        Section2();
    
        // 3
        Section3();
    
        // 4
        Section4();
    
        // 5
        Section5();
    
        system("pause");
        return 0;
    }
    
    // 第1节内容:进制(System of Numeration)
    static void Section1()
    {
        std::cout << "Section1: System of Numeration" << std::endl;
    
        // 2 8 16 的赋值内置函数
        int num2Int32Equal = 0b1100;
        int num8Int32Equal = 0742;
        int num16Int32Equal = 0xfffe;
    
        std::cout << "\t Built-in function:" << std::endl;
        std::cout << "\t bitset<8>(12) = " << std::bitset<8>(12) << std::endl;
        std::cout << "\t std::oct << 482 = " << std::oct << 482 << std::endl;
        std::cout << "\t std::hex << 65534 = " << std::hex << 65534 << std::endl;
    
        std::cout << std::dec;
        std::cout << "\t int num2Int32Equal = 0b1100; -> num2Int32Equal is " 
            << num2Int32Equal << std::endl;
        std::cout << "\t int num8Int32Equal = 0742; -> num2Int32Equal is " 
            << num8Int32Equal << std::endl;
        std::cout << "\t int num16Int32Equal = 0xfffe; -> num16Int32Equal is " 
            << num16Int32Equal << std::endl;
    
        std::cout << std::endl;
    }
    
    // 第2节内容:其它进制 转 10进制
    static void Section2()
    {
        std::cout << "Section2: Others to DEC" << std::endl;
    
        std::string num2 = "10000001";
        std::string num16 = "81";
        std::string num8 = "201";
    
        long long result2 = NumerationConversion::ConvertOtherToTen(num2, 2);
        long long result16 = NumerationConversion::ConvertOtherToTen(num16, 16);
        long long result8 = NumerationConversion::ConvertOtherToTen(num8, 8);
    
        std::cout << "\t b " << PrettyNum2(num2) << " -> " 
            << std::to_string(result2) << std::endl;
        std::cout << "\t x " << num16 << " -> " 
            << std::to_string(result16) << std::endl;
        std::cout << "\t o " << num8 << " -> " 
            << std::to_string(result8) << std::endl;
    
        std::cout << std::endl;
    }
    
    // 第3节内容:10进制 转 其它进制
    static void Section3()
    {
        std::cout << "Section3: DEC to others" << std::endl;
    
        int num10 = 96783;
    
        std::string num16 = NumerationConversion::ConvertTenToOther(num10, 16);
        std::string num2 = NumerationConversion::ConvertTenToOther(num10, 2);
        std::string num8 = NumerationConversion::ConvertTenToOther(num10, 8);
    
        std::cout << "\t " << std::to_string(num10) << " -> x " << num16 << std::endl;
        std::cout << "\t " << std::to_string(num10) << " -> b " << PrettyNum2(num2) << std::endl;
        std::cout << "\t " << std::to_string(num10) << " -> o " << num8 << std::endl;
    
        std::cout << std::endl;
    }
    
    // 第4节内容:二进制与其乘方进制(BIN and Power N)
    static void Section4()
    {
        std::cout << "Section4: BIN and Power N" << std::endl;
    
        // 我们的方法有大小写之分
        std::map<unsigned, std::string> nums;
        nums[4] = "3123";
        nums[8] = "6372";
        nums[16] = "bc2f";
        nums[32] = "g2k1";
    
        std::map<unsigned, std::string> results;
        for (auto kvp : nums)
        {
            long long result = NumerationConversion::ConvertOtherToTen(kvp.second, kvp.first);
            results[kvp.first] = NumerationConversion::ConvertTenToOther((int)result, 2);
        }
    
        for(auto kvp : nums)
        {
            std::cout << "\t " 
                << std::to_string(kvp.first) << ": " << kvp.second << " -> b " 
                << PrettyNum2(results[kvp.first], (int)std::log2l(kvp.first)) << std::endl;
        }
    
        std::cout << std::endl;
    }
    
    // 第5节:位运算例子
    static void Section5()
    {
        std::cout << "Section5: Bitwise" << std::endl;
    
        std::string bin1 = "00010100";
        std::string bin2 = "10001101";
        long long value1 = NumerationConversion::ConvertOtherToTen(bin1, 2);
        long long value2 = NumerationConversion::ConvertOtherToTen(bin2, 2);
    
        std::cout << "\t " << bin1 << " & " << bin2 << " = " 
            << std::bitset<8>(value1 & value2) << std::endl;
        std::cout << "\t " << bin1 << " | " << bin2 << " = " 
            << std::bitset<8>(value1 | value2) << std::endl;
        std::cout << "\t " << "        " << "  ~" << bin2 << " = " 
            << std::bitset<8>(~value1) << std::endl;
        std::cout << "\t " << bin1 << " ^ " << bin2 << " = " 
            << std::bitset<8>(value1 ^ value2) << std::endl;
    
        std::cout << std::endl;
    }
    
    
    // 二进制左侧补0
    static std::string PadLeft2(std::string value, int n)
    {
        while ((value.length() % n) != 0)
        {
            value = "0" + value;
        }
        return value;
    }
    
    
    // 每n个字符加一个空格
    static std::string PrettyNum2(std::string num2, int n)
    {
        num2 = PadLeft2(num2, n);
    
        std::string result = "";
        int i = 1;
        for (std::string::iterator it = num2.begin(); it != num2.end(); it++)
        {
            result += *it;
            if (i % n == 0)
            {
                result += " ";
            }
            i++;
        }
    
        return result;
    }
    

输出为:

C++ Numeration Conversion
Section1: System of Numeration
         Built-in function:
         bitset<8>(12) = 00001100
         std::oct << 482 = 742
         std::hex << 65534 = fffe
         int num2Int32Equal = 0b1100; -> num2Int32Equal is 12
         int num8Int32Equal = 0742; -> num2Int32Equal is 482
         int num16Int32Equal = 0xfffe; -> num16Int32Equal is 65534

Section2: Others to DEC
         b 1000 0001  -> 129
         x 81 -> 129
         o 201 -> 129

Section3: DEC to others
         96783 -> x 17a0f
         96783 -> b 0001 0111 1010 0000 1111
         96783 -> o 275017

Section4: BIN and Power N
         4: 3123 -> b 11 01 10 11
         8: 6372 -> b 110 011 111 010
         16: bc2f -> b 1011 1100 0010 1111
         32: g2k1 -> b 10000 00010 10100 00001

Section5: Bitwise
         00010100 & 10001101 = 00000100
         00010100 | 10001101 = 10011101
                   ~10001101 = 11101011
         00010100 ^ 10001101 = 10011001

请按任意键继续. . .


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值