基础知识点
ECMAScript中的进制
ES中进制规范基于C语言,随着发展然后进行了改进。下面列举JavaScript不同进制写法:
// 二进制 Binary system
// 以0b或0B开头
var FLT_SIGNBIT = 0b10000000000000000000000000000000; // 2147483648
var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607
// 二进制展示(方便展示,理解上却更难了)
// 正数:就是正数的原码
// 负数:负号+正数的原码
// 不是数值的二进制补码
parseInt(-10).toString(2) // -1010
// 八进制 Octal number system
// 以0开头,ECMAScript 6支持0o
var n = 0755; // 493
var m = 0644; // 420
var e = 0o755; // 493 ECMAScript 6规范
// 十进制 Decimal system
// 以0开头,但是后面跟8以下会当作八进制处理
var d = 1234567890;
var l = 0888; // 888 十进制
var 0 = 0777; // 511 八进制
// 十六进制 Hexadecimal
// 以0x或0X开头
0xFFFFFFFFFFFFFFFFF // 295147905179352830000
0x123456789ABCDEF // 81985529216486900
0XA // 10
原码、反码、补码
先让我们看下 1
和 -1
原码、反码、补码,然后我们通过这个2个数字来解释原码、反码、补码。
JavaScript 负数显示 是 负号+原码(理论上方便查看),比如parseInt(-10).toString(2)
二进制展示输出是-1010
直接原码进行 有符号
的加计算 ,结果十进制是 -2
,这个结果明显是错误的。符号直接参与运算有问题。
- 原码:
- 数字的二进制表示,有符号数,最高位作为符号位,
0
表示+
,1
表示-
,无符号数 即无符号位 - 反码:
- 正数和
+0
其原码本身就是反码 - 负数和
-0
符号位与原码中一样,保持不变,其余位数逐位取反,1
换成0
,0
换成1
- 补码:
- 正数和
+0
其原码本身就是补码 - 负数和
-0
先计算其反码,然后反码加上1
(例如8位的加0000 0001
),得到补码
数据在内存中是以补码形式存储(方便换算),原码和补码是在运行过程进行转换的。 通过补码计算得到补码,然后转成反码,再转成原码(这里不是减 1
还是加 1
)。
-0
原码和反码不一致,所以出现了补码,反码成了中间过渡。
字节序
什么是字节?
大部分系统8个二进制位(Bit)构成一个字节(Byte)单元,一个字节可以存储一个英文字母或半个汉字。
经常听说汉字需要占2个字节(Byte)?
现在基本使用统一的字符集 Unicode
,规定的是字符的十六进制,基本常用字符的在Plane 0(0000–FFFF)里面,如英文 A
字母 U+0041
,汉字 范围是 U+4E00 ~ U+9FA5
,是 4个十六进制数即可表示一个字符 。
1 byte = 8 bit
那 8 bit
可以存储的数值范围:
- 无符号数值范围
0~255
- 有符号数值范围(符号占1位,1表示负数,0表示正数)
-128~127
十六进制转二进制,1位十六进制对应4 bit二进制,1个 Unicode 字符由4位十六进制组成。所以 Unicode 都需要 2个字节(Byte)。
这怎么英文也要2个字节了?
我们先看下十六进制转二进制,十六进制数与二进制有一一对照表,这里不展开。
中文 U+4E07
汉字 万
,看下图例子:
英文 U+0041
即 A
,看下图例子: