侧边栏壁纸
  • 累计撰写 218 篇文章
  • 累计创建 59 个标签
  • 累计收到 5 条评论

计算机中负数的表示方法

barwe
2022-04-29 / 0 评论 / 0 点赞 / 1,063 阅读 / 2,562 字
温馨提示:
本文最后更新于 2022-04-30,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

进位计数制

简称 进制,X 进制表示逢 X 进 1。进位之后,原来位置上的符号又变成了初始符号。

以十进制为例,9 + 1 会发生进位,结果为 10,原始位置的符号又变成了 0,而 0 是 X 进制中的 X 个有序符号的第一个。

进位计数法实现了用有限的符号来表示无限的数字,它是相对于无进制的计数方法而言的。

无进制的计数方法有结绳记事、唱票的“正”字计数法等。

X 进制表示每位可以使用 X 个字符,这个 X 就是 基数,例如十进制用 0 ~ 9 这九个符号来表示。

十六进制用 0 ~ 9, A, B, C, D, E, F 这十六个符号来表示,而二进制只需要 0 和 1 这两个符号来表示。

计数符号本身没有特别含义,只是我们习惯了十进制计数法,所以 0 ~ 9 才表示我们以为的那个数字。

数的几个基本概念

以十进制数 374 为例,它实际上可拆分成
image-20220430013126255

数码:即每个位置可用的计数符号,例如十进制的数码就是0,1,2,3,4,5,6,7,8,9

位数:进制计数法不同数码在不同位置上的含义不同,例如 4 在第 0 位上,3 在第 2 位上

基数:每一位上可用的符号个数,例如十进制每位可用的符号有 10 个,基数为 10;X 进制的基数就是 X

位权:每一位上的单位 1 表示的实际大小,例如 3 所在的位上 1 表示的实际上是 102;X 进制第 i 位(i=0,1,...)的位权是 Xi

一些特殊的进制

除了二进制、八进制、十进制和十六进制外,生活中的许多计数法都可以看做不同的进制:

  • 秒针和分针每过 60 下进一位变成一分或者一个小时,时针每转两圈进位变成一天
  • 周数每过 7 天又会重新开始循环,但是本年的已过周数会加 1
  • 将一个物体旋转 360 度后所在的位置跟原来一模一样
  • ……

进制的另一个特点是,在不考虑进位的情况下,一个数减去一个数必然可以通过它加上另一个数实现,例如:

  • 将指向 15 分的分针正拨 15 下和倒拨 45 下都会指向 30 分(60 为一个周期)
  • 周三这天往后数三天和往前数四天都是周六(7 为一个周期)
  • ……

在上面的例子中,60 是一种特殊的进制,因为并没有设计出 60 分符号。但是如果我们将 0 ~ 59 这 60 个数看做是独立的符号,它也是一个完备的 60 进制计数系统,即时我们在用十进制表示它,例如 00:59 + 00:02 = 01:01。

原数和补数

我们约定了一个周期比如 60,现在考虑 0 ~ 59 这 60 个数的加减法运算。

如果两个数的和大于等于 60,则发生进位,减掉 60 可得到忽略进位后的结果,例如

  • 15 + 30 => 45
  • 15 + 45 => 00
  • 30 + 40 => 10

如果两个数的差小于 0,则发生借位,加上 60 可得到忽略借位后的结果,例如

  • 45 - 10 => 30
  • 10 - 20 => 50
  • 20 - 20 => 00

对于 0 ~ 59 中的某一个数 x,总能找到一组 a, b 使得 x + a = x - b,跟上面拨表针的例子类似。

这样,我们可以将 x - b 转化为求 x + a,不难看出 a + b = T。

在约定的周期 T 下,假设 a + b = T,则 a 和 b 互补,假设 a 是 原数,b 就是 补数,T 也叫做

对模 T 内的数的减法运算,可以转化为这个数的补数的加法运算,例如

  • 15 - 3 = 15 + 57 = 12
  • 15 - 20 = 15 + 40 = 5
  • 15 - 15 = 15 + 45 = 0

上述特点看起来没啥实用性,但是用来理解理解计算机中的 补码 还是很有帮助的。

补数在计算机中的应用

字节 是计算机存储和传输数据的基本单位,1 byte = 8 bits。

一个字节可以转换为一个数,有符号时是 -128 ~ 127,无符号时是 0 ~ 255。

以有符号 byte 类型为例,计算机用 0000 0001 来存储 1 很容易理解,那么计算机怎么存储 -1 呢?

有符号时最高位为 1 表示负数,那么 -1 的存储格式是 1000 0001 吗?

因为符号位是我们认为规定的,计算机可不知道什么是符号,基于上面假设我们计算 1 + (-1):

0000 0001 + 1000 0001 = 1000 0010 => -2 显然不对

我们期望的是

0000 0001 + xxxx xxxx = 0000 0000

用 0000 0000 来表示 0 是一个易于理解的前提,然而事实上,考虑有符号时,1000 0000 也可用来表示 0。因为符号是人为规定的,所以计算机可不觉得 0000 0000 和 1000 0000 是相等的。

另一个事实:计算机只能计算加法,在计算单个字节数值的加法时溢出的进位会被直接舍弃掉,例如

  • 1111 1111 + 0000 0001 => 1 0000 0000 => 0000 0000

于是我们发现,当 xxxx xxxx 等于 1111 1111 时,它加上 1 等于 0,不难假设,-1 可以用 1111 1111 来表示。

进一步可推断,对于任意一个正数 0xxxx xxxx 我们都能在一个字节内找到它的相反数表示。

原数和相反数是通过舍弃溢出的进位来实现相加等于零的,这样我们就能直接从原数推断出其相反数的表示

二进制原数的相反数 = 1 0000 0000 - 二进制原数

根据二进制的特点

1111 1111 - 二进制数 = 这个二进制数的所有位取反

所以

二进制原数的相反数 = 二进制原数按位取反 + 1

这样计算减去某个二进制数,可以转化为计算加上这个这个二进制数的相反数。

所以得出结论:

  • 计算机中的 1111 1111 表示 -1,而 0000 0001 表示 1
  • -1 和 1 是相反数,而 1111 1111 和 0000 0001 是模为 1 0000 0000 下的互补数

此外,按照符号位的约定,0000 0000 和 1000 0000 都应该用来表示 0,但这会在计算机中引起不一致性,因为计算机会将它们看做两个不同的东西。

按照互补数和相反数的转换关系,例如我们计算 -127 - 1:

对 127 的二进制表示按位取反再加 1 得到 -127 的表示:1000 0001
-1 的二进制表示:1111 1111
故而计算结果为 1000 0001 + 1111 1111 => 1 1000 0000 => 1000 000

这里我们发现,我们以为 1000 0000 应该也可以表示 0,但是实际上它表示的是 -128。

所以对于有符号的 byte 类型:

  • 0000 0000 ~ 0111 1111 表示 0 ~ 127
  • 1000 0000 表示 -128
  • 1000 0001 ~ 1111 1111 表示 -127 ~ -1
  • 整个有符号 byte 类型能表示的数是 -128 ~ 127

总结一下,二进制补数可以将减法运算转化为加法运算,它建立了十进制数与二进制的映射,这种映射并不完全等价于我们通常学习的进制转换方式(正数一致,负数不一致),通过这种转换,计算机能够通过仅计算加法来计算我们假设的减法表达式,而且事实上,计算机只能计算加法。

0

评论区