A-level 计算机科学/AQA/处理和编程技术/计算机中的数据表示
如您所知,我们通常使用的计数系统是**十进制**,而计算机使用的二进制系统是**二进制**。**十六进制**是一种**十六进制**数制。在十六进制中,使用数字 0-9,就像在十进制中一样,但字母 A-F 也用于表示数字 10-15。下表显示了十进制的数字 0-16 以及它们的二进制和十六进制等效值
十六进制 | 二进制 | 十进制 |
---|---|---|
0 | 0000 | 0 |
1 | 0001 | 1 |
2 | 0010 | 2 |
3 | 0011 | 3 |
4 | 0100 | 4 |
5 | 0101 | 5 |
6 | 0110 | 6 |
7 | 0111 | 7 |
8 | 1000 | 8 |
9 | 1001 | 9 |
A | 1010 | 10 |
B | 1011 | 11 |
C | 1100 | 12 |
D | 1101 | 13 |
E | 1110 | 14 |
F | 1111 | 15 |
10 | 10000 | 16 |
您可能会从表格中注意到,一个十六进制数字可以准确地表示 4 个二进制位。十六进制对我们来说是一种简写二进制的简便方法,并且使使用长二进制数字更容易。
由于 4 个二进制位由一个十六进制数字表示,因此在两者之间进行转换很简单。您可以将二进制位分组为 4 组,从右边开始,并在需要时在左边添加额外的 0,然后将每组转换为它们相应的十六进制等效值。例如,数字 110110011110101 可以这样写
0110 1100 1111 0101
然后通过使用上面的表格,您可以将每组 4 位转换为十六进制
6 C F 5。
因此,二进制数 0110110011110101 在十六进制中是 6CF5。我们可以通过将两者都转换为十进制来检查这一点。首先我们将转换二进制数,因为您已经知道如何做到这一点
32768 | 16384 | 8192 | 4096 | 2048 | 1024 | 512 | 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 |
通过将各列相乘,然后将结果相加,答案是 27893。
注意,列标题都是 2 的幂,, , , ,等等。为了从十六进制转换为十进制,我们必须使用基数为 16 的幂作为列标题,如下所示
4096 | 256 | 16 | 1 |
---|---|---|---|
6 | C | F | 5 |
(您应该记住 A-F 的值)
将它们全部加起来得到 27893,表明 0110110011110101 等于 6CF5。
为了从十进制转换为十六进制,建议您先将数字转换为二进制,然后使用上述简单方法从二进制转换为十六进制。
- 注意:十六进制使用起来比纯二进制更容易理解。它**不会**占用更少的内存空间,只会占用更少的纸张空间!
计算机纯粹以二进制方式工作。这意味着它只使用 1 和 0,而且计算机无法使用 - 或 + 符号。计算机必须以不同的方式表示负数。
我们可以通过将最高有效位设为**符号位**来表示二进制中的负数,这将告诉我们该数是正数还是负数。一个 8 位数的列标题将如下所示
-128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
---|---|---|---|---|---|---|---|
1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 |
在这里,最高有效位是负数,其他位是正数。您从 -128 开始,按正常方式添加其他位。上面的例子在十进制中是 -67。-1 的二进制是 11111111。
请注意,只有在数字被指定为**有符号**时,您才使用最高有效位作为符号位。如果数字是**无符号**的,则 msb 为正数。
要找出二进制补码的数值,我们首先要标记它的符号位(最高位,最左边的位)。如果为 0,则该数字为正数,如果为 1,则该数字为负数。
0000 0101 (positive) 1111 1011 (negative)
要找出负数的数值,我们必须找到并保留最右边的 1 及其右边的所有位,然后将它左边的所有位翻转。以下是一个例子:
1111 1011 find the right most one 1111 1011 0000 0101 flip all the bits to its left
现在我们可以计算出这个新数字的数值,它是
128 64 32 16 8 4 2 1 0 0 0 0 0 1 0 1 4 + 1 = −5 (remember the sign you worked out earlier!)
再来一个更复杂的例子怎么样?
1111 1100 find the right most one 1111 1100 0000 0100 flip all the bits to its left
128 64 32 16 8 4 2 1 0 0 0 0 0 1 0 0 4 = −4 (remember the sign you worked out earlier!)
所以我们知道如何计算一个给定的负数的数值。我们如何计算一个正数的负数版本?就像这样……
取正数的二进制版本
0000 0101 (5) 0000 0101 find the right most one 0000 0101 1111 1011 flip all the bits to its left
所以现在我们可以看到正数和负数之间的区别
0000 0101 (5) 1111 1011 (−5)
当涉及到用二进制从一个数字中减去另一个数字时,事情会变得非常混乱。
X (82 denary) 0101 0010 Y (78 denary) 0100 1110 −
从 X 中减去 Y 的一个更容易的方法是将 Y 的负值加上 X 的值。
X−Y = X+(−Y)
要做到这一点,我们首先需要找到 Y 的负值
0100 1110 find the right most one 0100 1110 1011 0010 flip all the bits to its left
现在再尝试一下加法
0101 0010 X( 82 denary) 1011 0010 + Y(−78 denary) 0000 0100 (¹)¹¹¹ ¹ the one carried over the bit 9 is ignored
结果是
128 64 32 16 8 4 2 1 0 0 0 0 0 1 0 0 4 = 4 = 82-78
到目前为止,我们只处理了整数,或者说整数。我们需要一种方法在计算机系统中存储实数。
首先,我们应该看看十进制中表示分数的方法之一。
10 | 1 | |||
---|---|---|---|---|
1 | 2 | . | 7 | 5 |
正如你所见,列标题已经扩展到 和 。我们可以在二进制中做同样的事情,列标题是、 等等。因此,二进制中的 12.75 为
8 | 4 | 2 | 1 | |||
---|---|---|---|---|---|---|
1 | 1 | 0 | 0 | . | 1 | 1 |
请注意,对于小数点后的相同位数,二进制数的精度较低。它只能取 4 个不同的值,而十进制数可以用两位数字进行 100 个不同的划分。
如果你学习物理或化学等其他科目,你可能会遇到这样的浮点数
(Planck's constant)
第一位定义了数字的非零部分,称为尾数,第二部分定义了我们想要移动小数点的位数,这被称为指数,当小数点向右移动时可以为正,当小数点向左移动时可以为负。
如果你想完全写出那个数字,你就必须将小数点在指数中向左移动 34 位,结果是
这将需要很长时间来写,而且人眼很难看清有多少个零。因此,当我们可以接受一定程度的精度(6.63 = 3 位有效数字)时,我们可以用少数位数存储像普朗克常数这样的大数字。你总是权衡数字的范围(或范围)与其精度(有效位数)。
二进制数也是如此,这一点甚至更为重要。当你处理数字及其计算表示时,你必须始终了解这些数字在内存中占用多少空间。正如我们在上面的例子中看到的,一个数字的非浮点数表示形式可能需要占用一个不可行的位数,想象一下存储 在二进制中需要多少位? (别担心,这个问题是修辞性的)
二进制浮点数可能由 2、3 或 4 个字节组成,但是你只需要关心 2 字节 (16 位) 的类型。前 10 位是尾数,最后 6 位是指数。
就像十进制浮点数表示一样,二进制浮点数也会有尾数和指数,但由于你处理的是二进制 (以 2 为底),你必须记住,你需要使用 而不是 。
定点二进制允许计算机保存小数,但由于其性质,其范围非常有限。即使使用 4 个字节保存每个数字,并将 8 位用于小数点后的分数部分,所能保存的最大数字也只有 800 万多一点。为了保存非常大的数字,需要另一种格式。
在十进制中,非常大的数字可以用尾数和指数来表示。例如 0.12²。这里 0.12 是尾数,² 是指数。尾数保存主要数字,指数定义小数点应该放在哪里。
同样的技术可以用于二进制数。例如,可以将两个字节分成 10 位用于尾数,其余 6 位用于指数。这允许使用更大的数字范围。
在计算二进制浮点数时,需要经过几个步骤。实际上这就像迪斯科舞的舞步一样 - 在此页面上被称为 Noorgat 舞,Kemp 变奏(但你不会被测试名字,但它应该帮助你记住)
- 符号 - 找到尾数的符号 (记下来)
- 滑动 - 找到指数的值,以及它是正数还是负数
- 反弹 - 根据指数的要求移动小数点,负指数向左移动,正指数向右移动
- 翻转 - 如果尾数为负,则对其执行二进制补码操作
- 游泳 - 从小数点开始计算尾数的值。现在确保你参考你在符号步骤中记录的符号。
让我们试试。我们给定以下 16 位浮点数,其中 10 位用于尾数,6 位用于指数。记住小数点位于第一位和第二位有效位之间
我们需要执行的第一个操作是符号,找出指数的符号
It is 0 so the mantissa is positive
Noorgat 舞的第二步是滑动,我们需要找到指数的值,即数字的最后 6 位
So we know that the exponent is of size positive one and we will have to move the decimal point
one place to the right.
Noorgat 舞的第三步是反弹,即根据滑动的指示将尾数的小数点移动指定的位数,即向右移动一位。就像这样
第四步是可选的翻转。回到符号步骤,查看尾数是否为负数。不是吗?好吧,你可以跳过这一步,因为我们只在尾数为负数时翻转数字。
第五步也是最后一步是游泳。单独考虑尾数,现在我们可以计算出浮点数的值。从中间开始,将左侧的每个数字标记为 等等。右侧的每个数字 等等。
Voila! the answer is 1
规范化数字
[edit | edit source]在处理二进制浮点数时,必须确保前两位不同。也就是说
绝对不
这是因为我们必须确保我们使用的空间被最有效地使用。例如,如果我们取一个十进制浮点数,例如
(Planck's constant)
如果我们把它改写为
(Planck's constant)
那么你可以看到表示形式多占了 2 个字符,即两个额外的 0,即使它代表完全相同的数字。当你不关心数字占用了多少字符时,这可能是可以接受的,但在二进制和计算机中,数字占用的空间非常重要,我们需要最有效的表示形式。对于固定数量的位,数字的规范化表示形式将以尽可能高的精度显示数字。你必须确保你的规范化操作不会改变尾数的符号。 考虑一个二进制浮点数
我们可以看到数字以 开头。我们需要把它改成 才能使其规范化。为此,我们需要将小数点向右移动一位,并且为了保持与非规范化数字表示的相同数字,我们需要相应地更改指数。如果将小数点向右移动一位以规范化数字,我们需要将指数更改为向左移动一位以补偿。从而从当前指数中减去 1。
为了确保你已正确规范化,请检查
让我们尝试一个更复杂的例子
为了使尾数规范化,我们需要将小数点向右移动两位。为了保持与原始浮点数相同的值,我们需要将指数调整为小 2。
现在检查新的规范化值是否与原始值相同。