计算机中的数值表示
进位计数值:基数R+位权w
基数R
- R代表基本数码的个数,二进制就是0和1这2个数。
- R进制的主要特点是逢R进1.
- 如2进制,逢2进1,十进制,逢10进1
位权Wi
- 位权是指第i位上的数码的权重值,位权与数码所处的位置i有关。
- 例如R=10(十进制数),各个数码的权位10^i,i表示数码所处的位置。
- 如
十进制 11 = 1*10^1 + 1*10^0 = 11; 二进制 11 = 1 * 2 ^1 + 1 * 2 ^0 = 3
进制转换
二进制转10进制
- 按权展开,加权求和,如2进制111.11转为10进制
111.11 = 1 * 2 ^ 2 + 1 * 2 ^1 + 1 * 2 ^ 0 + 1 * 2 ^(-1) + 1 * 2 ^(-2)
= 4 + 2 + 1 + 0.5 + 0.25 = 7.75
十进制转2进制
- 整数部分:除2取余,直到商为0,最先得到的余数是最低为,最后得到的余数是最高位。
- 小数部分: 乘2取整, 直到积数为0或者达到精度要求为止,最先得到的整数是高位。
十进制 7.75
整数7,小数0.75;
7/2 = 3....1
3/2 = 1....1
1/2 = 0 ....1
整数部分的二进制就是111
小数:
0.75 * 2 = 1.5 => 1
0.5 * 2 = 1 => 1
小数部分就是11
所以7.75转为二进制就是111.11
计算机的数据
计算中的数据分为数值数据和非数值数据,数值数据又分为无符号数据和有符号数据。
数值数据
bit!!
-
bit比特是表示信息的最小单位
-
比特是二进制单位的缩写
-
比特只有两种状态 0和1
-
一般来说n比特的信息量可以表示出2的n次方种选择
// 一般来说n比特的信息量可以表示出2的n次方种选择 let a = 0b1000 // 8 // 3个bit,2^3 = 8种选择 0~7 console.log(a);
无符号数据!!
原码: 3个bit能表示8个数。 0,1,2,3,4,5,6,7
有符号数据!!
原码!!
1 符号: 用 0,1表示正负号,放在数值的最高位,0表示正数,1表示负数。
2 原码:3个bit能表示8个数字。如 +0 +1 +2 +3 -0 -1 -2 -3
000 001 010 011 100 101 110 111
+0 +1 +2 +3 -0 -1 -2 -3
这样有个缺陷: (+1)+(-2) = 001 + 110 = 111 = (-3)? 答案是错的。
反码:!!
正数不变,负数的除了符号位,其他位置全部取反。
如:
+0 +1 +2 +3 -0 -1 -2 -3
000 001 010 011 111 110 101 100
可以看到,除了符号位,其他位置跟正数全部是反着来的。那么(+1)+(-2) = 001 + 101 = 110 = (-1)正确。但是0有两个值,即000和111
补码:最高位溢出舍弃。!!
正数不变,负数在反码的基础上加1。
如:
0 +1 +2 +3 -1 -2 -3 -4
000 001 010 011 111 110 101 100
这样解决了可以带符号位进行运算不需要单独标识。
如 +1 + -2 = 001 + 110 = 111 = -1;
+1 + -1 = 001 + 111 = 1000(舍弃) = 000 = 0
解决了自然码正负0的表示方法。
实现了减法变加法。
- 计算机只有补码。原码和反码只是为了让你快速计算得到补码。
小数点表示
- 在计算机中,小数点及其位置是隐含规定的。小数点并不占用存储空间。
- 定点数: 小数点的位置是固定不变的,分为定点整数和定点小数。
- 浮点数:小数点的位置是会变化的。
定点小数
小数点隐含固定在最高数据位的左边,整数位则用于表示符号位,用于表示纯小数
X0(符号位) .(小数点隐含位置) X1X2...Xn(数值位)
如0.35, 0.45。 如二进制的0.110011 = 十进制的0.796875
定点整数
小数点位置隐含固定在最低为之后,最高位为符号位,用于表示纯整数。
X0(符号位) X1X2...Xn(数值位).(小数点隐含位置)
如(0110011.)2 = 51(10)
浮点数!!
- 对于既不是定点整数也不是定点小数的数,用浮点数表示。
- 在计算机中,通常把浮点数N分成阶码和尾数两部分来表示。
- 小数点位是由阶码规定的,因此是浮动的。
1.00101 尾数就是0.100101 阶码就是小数点的位置。 阶码如果为2,小数点就要往右移动两位,10.0101 如果为-2,就要往左移两位,0.00100101
- N=尾数*基数^阶码,尾数是一个规格化的纯小数。 如 (11.1)2 = 尾数0.111 * 基数2 ^10, 二进制,所以基数是2,阶码也是2,转为二进制就是10.
- 科学计数法,把一个数表示成a(1<= |a| <10)与10的n次幂相乘,可以节约时间和空间,如1100 = 1.1 * 10 ^ 3
IEEE754标准
- js采用的是双精度(64位)8个字节
- 符号位决定了一个数的正负,指数部分决定了数值的大小,小数有效部分决定了数值的精度。
符号位(1) 指数位(2~12共11位),小数有效位(13~64共52位)
如(3.5)10 = (11.1)2 = 1.11 * 2^ 1
0 000000000001 (对应指数1) 110...00(默认变成1.xxx,如1.11...00)(对应1.11)
符号位 指数位(11) 有效位(52)
- 一个数在js内部实际的表示形式: (-1)^符号位 * 1.有效位 * 2^指数位,
- 如上面:(3.5)10 = (11.1)2 = 0.111 * 2^ 10 = -1 ^ 0 + 1.11 * 2 ^ 1 = 3.5
- 精度最多53个二进制位, -(2^53 -1)到2^53 - 1
- 指数部分的最大值是2017,分一半表示负数,所以js能够表示的数值范围是2^1024 ~ 2 ^-1023
0.1 + 0.2 != 0.3
十进制0.1 => 二进制 => 0.0001100110011..... 十进制0.2 => 二进制 => 0.001101100110011.... 十进制0.3=> 二进制 => 0.01001100110011....
0.1 * 2= 0.2 // 0
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
0.4 * 2= 0.8 //0
0.8 * 2 = 1.6 //1
0.6 * 2 = 1.2 //1
...开始循环了
0.2 => 10进制
0.2 * 2 = 0.4 // 0
...开始循环
0.3 => 10进制
0.3 * 2 = 0.6 //0
0.6 * 2 = 1.2 //1
0.2 * 2 = 0.4 // 0
开始循环
他们三个是无限循环的小数。分别取出前10位相加
0.0001100110 (0.1)
+ 0.0011001100 (0.2)
= 0.0100110010
0.0100110011 (0.3)
可以明显看到,到第八位开始就不一样了。(10进制转2进制的精度问题)
js大数相加
列竖式方法,从低位向高位计算。
- 将原始数字进行倒序,从个位开始依次相加,满10进1。如下
123123123123...
+ 123123123123...
= 246246246246....一个一个加。
具体实现:
let num1 = "1234567890";
let num2 = "12345678";
// 将大数的每个数拆开,并且反转
let num1Array = num1
.split("")
.map((item) => parseInt(item))
.reverse();
let num2Array = num2
.split("")
.map((item) => parseInt(item))
.reverse();
// +1是因为两个数相加可能会进位。
const totalLength =
num1Array.length > num2Array.length
? num1Array.length + 1
: num2Array.length + 1;
//所得和
let sumArray = [].fill(0, 0, totalLength);
//先拷贝第一个数字
num1Array.forEach((item, index) => {
sumArray[index] = item;
});
//相加
let up = 0; //保存进位
num2Array.forEach((item, index) => {
sumArray[index] = sumArray[index] + item + up;
if (sumArray[index] > 9) {
//需要进位
sumArray[index] = sumArray[index] % 10;
up = 1;
} else {
up = 0; //不需要进位
}
});
if(sumArray[sumArray.length -1] === 0){
//最后一位为0,表示不用进位,直接抛弃
sumArray.pop()
}
console.log(sumArray.reverse().join(''));
console.log(parseInt(num1)+ parseInt(num2));
// 结果
1246913568
1246913568