进制 (二进制、八进制、十进制、十六进制 等) - 转换、字面量

创建时间:
2014-06-08 01:39
最近更新:
2018-08-11 16:42

各种 十进制 基础数据类型 转换为 二进制字符串 (基于 .NET Framework 类库 的实现)

步骤

  1. 调用 public static byte[] System.BitConverter.GetBytes(bool/char/double/float/short/ushort/int/uint/long/ulong value) 将各种 基础数据类型 转换为 字节数组。
  2. 调用 System.Collections.BitArray(byte[] bytes) 构造函数 将 字节数组 转换为 System.Collections.BitArray 类。
  3. 调用已封装的 Tl.BitAndByte 类 的 public static string BitArrayTo01(BitArray ba) 方法 遍历 System.Collections.BitArray 类 将每个 bit 转换为 01

Note: 2018-07-20 已将上述步骤实现为 TonyLibraryNet4 类库中的 Tl.Converter.ToBin() 系列重载。

MSDN 相关文档

  1. System.BitConverter 类 - Converts base data types to an array of bytes, and an array of bytes to base data types (将基数据类型转换为一个字节数组以及将一个字节数组转换为基数据类型). 该类为静态类。该类共有 10 个重载 public static byte[] GetBytes(bool/char/double/float/short/ushort/int/uint/long/ulong value) 将基数据类型转换为一个字节数组,以及反向转换的方法。
  2. System.Collections.BitArray 类 - Manages a compact array of bit values, which are represented as Booleans, where true indicates that the bit is on (1) and false indicates the bit is off (0) (管理位值的压缩数组,这些值以布尔值的形式表示,其中 true 表示此位为开 (1),false 表示此位为关 (0)).
  3. System.Collections.BitArray(byte[] bytes) 构造函数 - 构造函数 public BitArray(byte[] bytes) 初始化 BitArray 的新实例,该实例包含从指定的字节数组复制的位值。 参数 bytes 字节数组包含要复制的值,此处每个字节代表八个连续位。 The Least Significant Bit of each byte represents the lowest index value (每个字节最高有效位表示最小索引值): "bytes[0] & 1" represents bit 0 ("bytes[0] & 1" 表示位 0), "bytes[0] & 2" represents bit 1, "bytes[0] & 4" represents bit 2, and so on (依次类推). The first byte in the array represents bits 0 through 7, the second byte represents bits 8 through 15, and so on (数组中的第一个字节表示 0 到 7 位,第二个字节表示位 8 到 15,依此类推).

常用代码

//十进制数 与 二进制字符串 相互转换:
string binaryString = Convert.ToString(123, 2);
int i = Convert.ToInt32("1010", 2);

//十六进制数 转换为 二进制、十进制 字符串:
Convert.ToString(0xa, 2);
Convert.ToString(0xa, 10);

//二进制字符串 转换为 十六进制字符串 (两步组合):
string.Format("{0:x}", Convert.ToInt32("1010", 2));

//左填充、右对齐:
Convert.ToString(123, 2).PadLeft(8, '0')

常用代码 (JavaScript)

//二进制 与 十进制 相互转换:
parseInt('10000000000000000000000000000000000000000000000000001', 2).toString(2);

字面量 表示法

C#

以下输出均为 true:

//十六进制整数字面量
0x11 == 17
0X11 == 17

截至 2018-06-08 尚未找到 其他进制字面量表示法。

JavaScript

以下输出均为 true:

console.log(
    //二进制整数字面量
    0b11 === 3,
    0B11 === 3,
    //八进制整数字面量
    011  === 9,
    //十六进制整数字面量
    0x11 === 17,
    0X11 === 17
);

Resource - MSDN

十进制 转 二进制、八进制、十六进制 字符串

  1. System.Convert.ToString 方法 - 将 32 位带符号整数的值转换为其指定基的等效字符串表示形式。 public static string ToString(int value, int toBase). 基数 必须是 2、8、10 或 16。 如果 value 为正 且 toBase 是 2、 8 或 16,则返回的字符串将使用 符号数值表示法。如果 value 为负 且 toBase 是 2、 8 或 16,则返回的字符串将使用 2 的补数表示。这意味着高序位字节 (第 31 位) 的高顺序位被解释为符号位。 System.Convert 类 共提供了 4 个 ToString() 重载 来实现 "整数值 至 指定基数字符串" 的转换,即: ToString(byte/short/int/long value, int toBase)。只支持 byte、short、int、long 4 种类型,不支持 uint、ulong 等类型。只支持 "基数 2、8、10、16",不支持其它 进制。Note: 测试发现 Convert.ToString(int/long, 2) 返回的 二进制 不含前导 0,可通过 PadLeft(32, '0') 标准化,详见单元测试 TlTest.Converter_Test.ToBin_三种实现的对比测试()

Resource

  1. 短网址算法 之 10-62 进制转换

理解 进制

  • 数码: 用来表示进制数的元素。比如 二进制数的数码为 0, 1; 十进制数的数码为 0-9; 十六进制数的数码为 0-F
  • 数位: 数码 在数中的位置叫做 数位。
  • 基数: 数码的个数。比如 二进制数的基数为 2。十进制数的基数为 10。十六进制数的基数为 16。
  • 位权: 数制中每一固定位置对应的单位值称为位权。例如 十进制第二位的位权为 10^110,第三位的位权为 10^2100; 二进制第一位的位权为 2^01,第三位的位权为 2^24; 对于 N 进制数,整数部分第 i 位的位权为 N^(i-1),而小数部分第 j 位的位权为 N^-j

因此有: 每个数码所表示的数值 = 该数码值 * 所处位置的位权。

十进制的意义 是 各个 数位 的 数码 与其 位权数 乘积之和,例如:

DEC(3135) =
3*10^3 +
1*10^2 +
3*10^1 +
5*10^0
DEC(365.32) =
3*10^2 +
6*10^1 +
5*10^0 +
3*10^-1 +
2*10^-2

各进制的计数规则

十进制 计数规则 为:

  • 基数为 10。
  • 有 10 个数字,即 0 至 9。
  • 逢 10 进 1,借 1 当 10。
  • 可以由多位数组成,从右向左依次为 个位、十位、百位、千位、万位...

二进制 计数规则 为:

  • 基数为 2
  • 有 2 个数字,即 0 和 1。
  • 逢 2 进 1,借 1 当 2。
  • 可以由多位数组成,从右向左依次为 1位、2位、4位、8位、16位、32位、64位、128位...

八进制 计数规则 为:

  • 基数为 8。
  • 由 8 个数字组成,0 至 7。
  • 逢 8 进 1,借 1 当 8。
  • 可以由多位数组成,从右向左依次为 1位、8位、64位、512位、4096位...

十六进制 计数规则 为:

  • 基数为 16。
  • 由 16 个数字组成,0 至 F。
  • 逢 16 进 1,借 1 当 16。
  • 可以由多位数组成,从右向左依次为 1位、16位、256位、4096位、65536位...

二进制数 转换为 十进制数

二进制数 转换成 十进制数 的基本做法是 把二进制数首先写成加权系数展开式,然后按十进制加法规则求和,这种做法称为 "按权相加" 法。

Example

BIN(110.11) =
1*2^2 +
1*2^1 +
0*2^0 +
1*2^-1 +
1*2^-2 =
4 + 2 + 0 + 1/2 + 1/4 =
DEC(6.75)

Example

BIN(1010101.1011) =
1*2^6 +
0*2^5 +
1*2^4 +
0*2^3 +
1*2^2 +
0*2^1 +
1*2^0 +
1*2^-1 +
0*2^-2 +
1*2^-3 +
1*2^-4 =
64 + 0 + 16 + 0 + 4 + 0 + 1 + 1/2 + 0 + 1/8 + 1/16 =
DEC(85.6875)

Example

二进制数 11101.010 转换为十进制:
整数部分: 11101 = (1*2^4) + (1*2^3) + (1*2^2) + (0*2^1) + (1*2^0) = 16 + 8 + 4 + 0 + 1 = 29
分数部分: 0.010 = 0.01 = (0/2^1) + (1/2^2) = 0 + 0.25 = 0.25
结果是: 29 + 0.25 = 29.25

Example

假设上例中 11101.010 这个数是十进制,做以下转换,对比之下可以很好地了解进制的规律:
整数部分: 11101 = 1*10^4 + 1*10^3 + 1*10^2 + 0*10^1 + 1*10^0 = 11101
分数部分: 0.010 = 0.01 = (0/10^1) + (1/10^2) = 0 + 0.01 = 0.01

Example

二进制数 110.11 可表示为 (1*2^2) + (1*2^1) + (0*2^0) + (1*2^-1) + (1*2^-2)

十进制数 转换为 二进制数

十进制数 转换为 二进制数 时,由于整数和小数的转换方法不同,所以先将十进制数的整数部分和小数部分分别转换后,再加以合并。例如,合并以下两例的结果可得出 DEC(173.8125) = BIN(10101101.1101)

十进制整数 转换为 二进制整数

  • 简单点说: 通常采用 "除二取余法",即用 2 连续除十进制数,直到商为 0,逆序排列余数即可得到二进制结果。
  • 啰嗦点说: 十进制整数 转换为 二进制整数 采用 "除二取余,逆序排列" 法。具体做法是: 用 2 去除十进制整数,可以得到一个商和余数; 再用 2 去除商,又会得到一个商和余数,如此进行,直到商为 0 时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来。

Example

173 / 2 = 86 余 1
 86 / 2 = 43 余 0
 43 / 2 = 21 余 1
 21 / 2 = 10 余 1
 10 / 2 =  5 余 0
  5 / 2 =  2 余 1
  2 / 2 =  1 余 0
  1 / 2 =  0 余 1

DEC(173) = BIN(1011 0101)

Example

将 25 转换为二进制:

25 / 2 = 12 //余 1
12 / 2 =  6 //余 0
 6 / 2 =  3 //余 0
 3 / 2 =  1 //余 1
 1 / 2 =  0 //余 1

由下往上数,得到 25 的二进制 ``11001``。

十进制小数 转换为 二进制小数

十进制小数 转换为 二进制小数 采用 "乘二取整,顺序排列" 法。具体做法是: 用 2 去乘十进制小数,可以得到积,将积的整数部分取出,再用 2 乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的小数部分为零,或者达到所要求的精度为止。然后把取出的整数部分按顺序排列起来,先取的整数作为二进制小数的高位有效位,后取的整数作为低位有效位。

Example

DEC(0.625) = BIN(0.101):

0.625 * 2 = 1.25  取出整数部分: 1
0.25  * 2 = 0.5   取出整数部分: 0
0.5   * 2 = 1     取出整数部分: 1

Example

DEC(0.8125) = BIN(0.1101):

0.8125 * 2 = 1.625  取出整数部分; 1
0.625  * 2 = 1.25   取出整数部分: 1
0.25   * 2 = 0.5    取出整数部分: 0
0.5    * 2 = 1      取出整数部分: 1

Example

DEC(0.7) = BIN(0.1 0110 0110...):

0.7 * 2 = 1.4   取出整数部分: 1
0.4 * 2 = 0.8   取出整数部分: 0
0.8 * 2 = 1.6   取出整数部分: 1
0.6 * 2 = 1.2   取出整数部分: 1
0.2 * 2 = 0.4   取出整数部分: 0 
0.4 * 2 = 0.8   取出整数部分: 0
0.8 * 2 = 1.6   取出整数部分: 1
0.6 * 2 = 1.2   取出整数部分: 1
0.2 * 2 = 0.4   取出整数部分: 0

Note: 这是一个二进制循环小数。循环节为 BIN(0110)

十进制小数 转换为 八进制小数

方法: 乘 8 取整

Example

0.71875 * 8 = 5.75      取出整数部分: 5
0.75    * 8 = 6.0       取出整数部分: 6
DEC(0.71875) = OCT(0.56)

十进制小数 转换为 十六进制小数

方法: 乘 16 取整

Example

0.142578125 * 16 = 2.28125  取出整数部分: 2
0.28125     * 16 = 4.5      取出整数部分: 4
0.5         * 16 = 8.0      取出整数部分: 8
DEC(0.142578125) = HEX(0.248)

二进制数 与 八进制数 之间的转换

转换方法: 以小数点为界,分别向左右 每三位二进制数 合并成 一位八进制数,或 每一位八进制数 展开成 三位二进制数,不足三位者补 0。

Example

OCT(423.45 = BIN(100 010 011.100 101)

Example

BIN(  1 001 001.110 1  ) =
BIN(001 001 001.110 100) =
OCT(111.64)

二进制数 与 十六进制数 之间的转换

转换方法: 以小数点为界,分别向左右 每四位二进制数 合并成 一位十六进制数,或 每一位十六进制数 展开成 四位二进制数,不足四位者补 0。

Example

HEX(ABCD.EF) = BIN(1010 1011 1100 1101.1110 1111)

Example

BIN( 101 1011 0100 1011.0110 1) =
BIN(0101 1011 0100 1011.0110 1000) =
HEX(5B4B.68)