赞
踩
每一位的权由基数的幂次决定,不同位上的数有着不同的权值,这称为位权表示法,同时基数也代表着数码的个数。
特点为:
对于任意一个k进制数A: A = A n A n − 1 . . . A 1 A 0 . A − 1 A − 2 . . . A − m ( 并 列 表 示 法 ) = A n × k n + A n − 1 × k n − 1 + . . . + A 1 × k 1 + A 0 × k 0 + A − 1 × k − 1 + . . . + A − m × k − m ( 多 项 式 表 示 法 ) = ∑ i = n − m A i × k i A = A_nA_{n-1}...A_1A_0\ .\ A_{-1}A_{-2}...A_{-m}(并列表示法) \\\ \ \ \ \ \ \ \ \ \ \ \ =A_n\times k^n+A_{n-1}\times k^{n-1}+...+ A_1\times k^1+A_0\times k^0+A_{-1}\times k^{-1}+...+A_{-m}\times k^{-m}(多项式表示法)\\=\sum_{i = n}^{-m}A_i\times k^i\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ A=AnAn−1...A1A0 . A−1A−2...A−m(并列表示法) =An×kn+An−1×kn−1+...+A1×k1+A0×k0+A−1×k−1+...+A−m×k−m(多项式表示法)=i=n∑−mAi×ki
基于此的二(可以是k)进制转化为十进制程序:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
char num[30];
scanf("%s", num);
int n, m = 0, flag = 0, len = (int)strlen(num);
for (int i = 0; i < len; i ++)
{
if (flag) m ++;
if (num[i] == '.') flag = 1;
}
if (flag) n = len - m - 2;//字符串中含小数点
else n = len - m - 1;//不含小数点
// m为小数部分的位数,n为整数部分的位数-1
double ans = 0;
for (int i = 0, j = n; i < len; i ++)
{
if (num[i] == '.') continue; //跳过小数点
ans += (num[i] - '0') * pow(2, j);
j --;
}
cout << ans;
return 0;
}
常见进制
十六进制中的特殊数码:
数码 | 数字 |
---|---|
A | 10 |
B | 11 |
C | 12 |
D | 13 |
E | 14 |
F | 15 |
常见二进制数 |
0000 | 0 |
0001 | 1 |
0010 | 2 |
0011 | 3 |
0100 | 4 |
0101 | 5 |
0110 | 6 |
0111 | 7 |
1000 | 8 |
1001 | 9 |
1010 | 10 |
1011 | 11 |
1100 | 12 |
1101 | 13 |
1110 | 14 |
1111 | 15 |
1000 0000 | 128 |
1111 1111 | 255 |
0.1 | 0.5 |
0.01 | 0.25 |
0.001 | 0.125 |
0.0001 | 0.0625 |
二进制的加法、乘法
加法 | 乘法 |
---|---|
0 + 0 = 0 | 0 × \times × 0 = 0 |
0 + 1 = 1 | 0 × \times × 1 = 0 |
1 + 0 = 1 | 1 × \times × 0 = 0 |
1 + 1 = 10 | 1 × \times × 1 = 1 |
注意到:十进制小数并不是都能够用有限位的其它进制数精确地表示,这时应根据精度要求转换到一定的位数为止。
要求精度为
1
0
−
k
10^{-k}
10−k时,设二进制小数位数为
m
m
m,有:
2
−
m
≤
1
0
−
k
⟹
m
≥
k
lg
2
≈
3.32
k
2^{-m}\le 10^{-k}\Longrightarrow m\ge\frac{k}{\lg2}\approx3.32k
2−m≤10−k⟹m≥lg2k≈3.32k,根据这种方法可以很方便的求出转换后的二进制小数的位数。
一般当要求二进制数取
m
m
m位小数时,可求出
m
+
1
m+1
m+1位,然后对最低位做0舍1入处理。
如果一个十进制数既有整数部分又有小数部分,则应将整数部分和小数部分分别进行转化,再把两者结果相加。
特殊技巧:
一个数除以
2
n
2^n
2n,就是将该数的二进制表示中的小数点左移
n
n
n位。
例如
13
13
13(8+4+1)的二进制形式为:1101,因此
13
16
\frac{13}{16}
1613的二进制表示为:0.1101。
一个数乘以 2 n 2^n 2n,就是将该数的二进制表示中的小数点右移 n n n位。
3位二进制数是1位八进制数,因此将二进制数转换为八进制数的方法为:
八进制转换为二进制,只需将每一位转换为对应的二进制数即可。
4位二进制数是1位十六进制数,则转换方法类似于二进制、八进制之间的转换。
将带‘ ± \pm ±’的二进制数称为真值;将符号和数值一起编码的二进制数称为机器码。例如:-1010就是真值,其对应的8位补码为1000 0110就是机器码。
n n n位二进制数的范围为: [ 0 , 2 n ) [0,2^n) [0,2n)
机器数有原码(signed magnitude number)、反码(diminished radix complement)、补码(radix complement)三种。
原码是最简单的机器码,就是将真值中的符号转化为0或1而已,即: 原 码 : 符 号 位 + 真 值 绝 对 值 原码:符号位+真值绝对值 原码:符号位+真值绝对值严格的数学定义为:
整数的原码
[
X
]
原
=
{
X
0
≤
X
<
2
n
2
n
−
X
−
2
n
<
X
≤
0
[X]_原=\left\{
整数0的原码有00...0
和10...0
两种。
在计算机中,每个数的表示都有位数限制。若一个整数用
n
n
n位来存储,由于最高位被设置为符号位,因此
n
n
n位原码的表示范围为:
−
(
2
n
−
1
−
1
)
∼
2
n
−
1
−
1
-(2^{n-1}-1) \ \sim\ 2^{n-1}-1
−(2n−1−1) ∼ 2n−1−1。
小数(
∈
(
−
1
,
1
)
\in(-1,1)
∈(−1,1))的原码
[
X
]
原
=
{
X
0
≤
X
<
1
1
−
X
−
1
<
X
≤
0
[X]_原=\left\{
小数0的原码有0.0...0
和1.0...0
两种。
严格的数学定义为:
00...0
和11...1
两种。n n n位反码的表示范围与原码相同: − ( 2 n − 1 − 1 ) ∼ 2 n − 1 − 1 -(2^{n-1}-1) \ \sim\ 2^{n-1}-1 −(2n−1−1) ∼ 2n−1−1
0.00...0
和1.11...1
两种。正数的补码和原码相同;负数的补码即反码+1。
严格的数学定义:
整数的补码
[
X
]
补
=
{
X
0
≤
X
<
2
n
2
n
+
1
+
X
−
2
n
<
X
≤
0
[X]_补=\left\{00...0
,因此补码的表示范围要比原码、反码多1。
-1的补码为:111...
,
−
2
n
−
1
-2^{n-1}
−2n−1的补码为:1000...
。
n
n
n位补码的表示范围为:
−
2
n
−
1
∼
2
n
−
1
−
1
-2^{n-1} \ \sim\ 2^{n-1}-1
−2n−1 ∼ 2n−1−1。
注意:有些数可能有补码表示,但不存在原码和反码表示。
小数的补码
[
X
]
补
=
{
X
0
≤
X
<
1
2
+
X
−
1
<
X
≤
0
[X]_补=\left\{0.0...0
总结:
计算机中广泛采用补码表示,少数机器采用原码进行存储和传输,计算时用补码表示。
十进制与二进制之间在代数结构上是等价的,但对于机器数,由于符号位的存在,运算会较为复杂,特别是减法运算。
为了让计算机底层设计更加简单,人们开始探索将符号位参与运算,并且采用只保留加法的方法。如此便引入了反码。
例如:将钟从11点调到3点,可以顺时针调4个小时,也可以逆时针调8个小时。
即计算机中所有数的小数点位置是固定不变的,因此在计算机内部,小数点无需用专门的记号表示出来。如此表示的数叫做定点数。
定点小数表示法——小数点固定在符号位与最高位之间
定点整数表示法——小数点固定在数值位的最后
定点小数表示法表示的数都是绝对值小于1的纯小数,对于二进制
m
+
1
m+1
m+1位的定点表示的数N,可以表示的范围为
∣
N
∣
≤
1
−
2
−
m
|N|≤1-2^{-m}
∣N∣≤1−2−m;
定点整数表示法表示的数都是绝对值在一定范围内的整数,对于二进制
m
+
1
m+1
m+1位的定点表示的数N,可以表示的范围为
∣
N
∣
≤
2
m
−
1
|N|≤2^{m}-1
∣N∣≤2m−1;
当超过这些范围时,为避免溢出,需要根据实际情况使用一个比例因子将所需存储的数缩小或放大,使用较为不便。
一个浮点数分为阶码(exponent)和尾数(mantissa)两部分:
阶码总是一个整数,正整数和负整数均可;尾数可以采用整数或纯小数两种形式。
通常情况下,在计算机内部,阶码采用 补码形式的整数 表示,尾数采用 原码形式的小数 表示,另外还有一个符号位。
浮点数的规格化形式:尾数的最高位必须是非零的有效位。
阶码和尾数所占用的位数可以灵活设定,由于阶码确定数的表示范围,尾数确定数的精度,所以字长一定时,分配给阶码的位数越多,表示的数的范围越大,但同时由于分配给尾数的位数减少,所以数的精度降低。
若阶码的位数为n,则阶码的范围为: − 2 n − 1 ∼ 2 n − 1 − 1 -2^{n-1}\sim2^{n-1}-1 −2n−1∼2n−1−1;若尾数的位数为m,则尾数的取值范围为: 2 − 1 ∼ 1 − 2 − m − 1 2^{-1}\sim 1-2^{-m-1} 2−1∼1−2−m−1(尾数最高位必须非零)
对于32位字长(单精度float),通常采用的分配方式为:1位符号位、8位阶码、23位尾数。
此时,阶码的范围为:
−
2
7
∼
2
7
−
1
-2^7\sim 2^7-1
−27∼27−1,尾数的范围为:
2
−
1
∼
1
−
2
−
24
2^{-1}\sim 1-2^{-24}
2−1∼1−2−24
则数值范围为:
当一个数超过浮点数的表示范围,将会发生溢出。
如果一个数的阶大于计算机所能表示的最大阶码,称为“上溢”,程序中断;如果一个数的阶小于计算机所能表示的最小阶码,称为“下溢”,该数视为0,仍可继续运算。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。