编程基础 - 进制转换(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=6048⋯15=378⋯0=23⋯10=1⋯7=0⋯1→xF→x0→xA→x7→x1
即最终结果为: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÷2⋮5÷22÷21÷2=48391⋯1=24195⋯1=2⋯1=1⋯0=0⋯1→b1→b1→b1→b0→b1
即最终结果为(不够4位补0):b 0001 0111 1010 0000 1111
-
八进制为 o 275017
-
其它进制同理。
4 二进制与其乘方进制(BIN and Power N)
在前面,我们看到二进制的计算是用2的次方计算。这样就造成了一个现象,二可以与乘方进制更快速的进行计算。
比如二进制与十六进制在计算机语言中是常用的,这是因为每4位的二进制数可表示为1位的十六进制数。这样只要记住4位二进制与1位十六进制对应关系,就不需要额外计算。同理其它进制也是这样。
如下表:
| 10 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 | 0 | 1 | 10 | 11 | 100 | 101 | 110 | 111 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
| 4 | 0 | 1 | 2 | 3 | 10 | 11 | 12 | 13 | 20 | 21 | 22 | 23 | 30 | 31 | 32 | 33 |
| 8 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 16 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
你会发现一个很有意思的现象:
-
二进制: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 | & | | | ~ | ^ |
|---|---|---|---|---|
| Left | 0001 0100 | 0001 0100 | 0001 0100 | 0001 0100 |
| Right | 1000 1101 | 1000 1101 | 1000 1101 | |
| Result | 0000 0100 | 1001 1101 | 1110 1011 | 1001 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
请按任意键继续. . .

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

被折叠的 条评论
为什么被折叠?



