以 4 位为例,我的理解是:
有符号数原码:
0 000 ~ 0 111 +0 ~ +7 前面的 0 表示是正数。
1 000 ~ 1 111 -0 ~ -7 前面的 1 表示是负数。
因为 +0 和 -0 实际上是相等的,也就是说,0 用原码表示的话有两种方式,这样的编码虽然人看起来要好懂一些,但是对于计算机来讲,有三个坏处:
1,违反了唯一性
2,浪费了一个位模式(排列方式)。因为理论上来讲 4 位二进制能表示 2^4 = 16 个不同的数,但是这里只表示了 -7 ~ +7 15 个数。
3,-7 明明是小于 -0 的,但是如果不把最高位当作符号位来看的话,1000 要比 1111 小。
我着重讲一下第三点。因为我们最终的目标是让符号也能够参与运算,也就是说,任何两个有符号数比较大小的时候,我们希望只需要减一下就可以了,因此原码的 1000 和 1111 它的顺序是反的,很不利于运算。
-128 在原码里是无法表示的。
基于以上三个原因,就引进了补码,在介绍补码之前,我先介绍一下反码:
正数的反码就是原码:
0 000 ~ 0 111 +0 ~ +7 反码
负数的反码就是对原码除符号位以外的其余各位进行取反:
1 111 ~ 1 000 -0 ~ -7 反码
这么做的好处是什么呢?好处是,解决了上面三个问题中的第三个问题。
但是另外两个问题还是没有解决。
下面引入的补码,就是为了解决另外两个问题。
补码:
补码的规则是:正数的补码和原码、反码形式相同。
负数的补码,等于反码 + 1,加 1 的时候,符号位也参与运算,溢出位被丢弃,不影响结果。
也就是说:
0 000 ~ 0 111 +0 ~ +7 补码
(1)0 000 ~ 1 001 -0 ~ -7 补码。
注意反码的 -0 也就是 1111 加了 1 之后,符号位产生了进位,溢出了,溢出之后,剩下的部分正好和 +0 一样了。
也就是说,第一个问题也解决了。
第一个问题解决了,那么就剩下第二个问题了,
因为从 -0 到 -7 依次是:
-7: 1 001
-6: 1 010
-5: 1 011
-4: 1 100
-3: 1 101
-2: 1 110
-1: 1 111
-0: 0 000
+1: 0 001
+2: 0 010
...
...
...
也就是说,还剩下 1 000 这个位模式是没用的,
因此就可以用它来表示其它的数。但是到底应该用它来表示 +128 好呢?还是 -128 好呢?
观察上面的序列,你会发现,如果溢出是正常的话,
上面的数列正好是连续的,
而 1 000 比 1 001 还要小 1,因此用来表示 -128 是合理的。加 1 之后正好等于 -127。
因此就用 1 000 来表示 -128 了。
分享到:
相关推荐
- `0 | (1 (sizeof(int) * 8 - 1))`进行按位或运算,结果为符号位为1且其他位都为0的32位数,即`int`类型的最小值。 #### 使用示例 ```c #include char lc(const char ch); char uc(const char ch); int max_...
其中,double类型的最大值为1.7976931348623158e+308,double类型的最小值为2.2250738585072014e-308。float类型的最大值为3.402823466e+38F,float类型的最小值也为3.402823466e+38F。 整数类型的最大值与最小值 ...
对于占用4个字节(32位)的有符号整型变量,它可以表示的最小值为-2,147,483,648(-2^31),最大值为2,147,483,647(2^31-1)。 示例代码: ```cpp int a = 2147483647; cout ; // 输出结果:2147483647 ``` ### ...
在一台典型的32位机器上,一个有符号的int型的取值范围为-2147483648 ~ 2147483647(-2^31 ~ (2^31-1))。也就是说,在一个4字节(32位)中,除去首位用于符号位表示正负外,其余的31位都是数字的有效位。 其次,...
2. **short int**: `short int`占用2个字节(16位),其最大值为32767,最小值为-32768。`unsigned short`则表示无符号的16位整型,范围从0到65535。 3. **int**: 在Keil MDK-ARM中,`int`同样占用4个字节(32位)...
如果 `long` 变量的值超出了 `int` 类型的最大范围(-2^31 至 2^31 - 1),转换将会丢失超出部分的信息。Java 提供了强制类型转换来执行这种转换,但需要程序员谨慎处理可能的溢出问题。例如: ```java long ll = ...
在Java编程中,数组是一种非常基础且重要的数据结构,它用于存储同类型的多个元素。在处理数组时,经常需要找出数组中的最大值和最小值,这对于数据分析、算法实现或者简单的数学计算都至关重要。本详细教程将指导你...
在C语言编程中,求一组整数中的最小值是一个常见的任务,尤其对于初学者来说,这是一个很好的练习。本文将详细讲解如何使用C语言通过三个变量来寻找三个输入整数中的最小值。 首先,我们需要理解C语言的基础知识。...
- `int` 和 `signed int`:通常为4个字节,取值范围为-2^31到2^31-1。 - `short` 和 `signed short`:通常为2个字节,取值范围为-2^15到2^15-1。 - `long` 和 `signed long`:在大多数现代系统上也是4个字节,...
在本文中,我们将深入探讨C51单片机的外部中断功能,特别是INT0、INT1、INT2、INT3以及INT4这五个中断源。C51单片机是Atmel公司生产的8051系列微控制器的一个变种,具有丰富的外设接口和中断系统,使得它广泛应用于...
在探讨C语言中int型取值范围为何设定为-2的15次方到2的15次方减1之前,我们首先需要理解二进制数的表示方式以及补码的概念,这对于理解整数类型的存储机制至关重要。 ### 二进制与原码 计算机内部使用二进制进行...
int 是一个 4 字节的整数类型,可以表示从 -2^31 到 2^31-1 的值。smallint 是一个 2 字节的整数类型,可以表示从 -32,768 到 32,767 的值。tinyint 是一个 1 字节的整数类型,可以表示从 0 到 255 的值。 在 ...
在这个问题中,我们关注的是一个特定的int数组{1, 3, 5, -2, 4, 6},我们需要计算这个数组中的最大值、最小值、元素和以及平均值。这些都是数据分析和算法基础中的关键概念。 1. **最大值**:数组中的最大值是指...
- `int8` 类型是一个8位有符号整数,最大值为127,最小值为-128。 - 当我们将 `byte` 类型转换为 `int8` 类型时,由于 `byte` 类型的值超出了 `int8` 的范围,因此会出现溢出,导致值变为-1。 #### 三、int和uint的...
1. **Int32到/从字节数组**:`Int32`在C#中表示32位带符号整数,范围从-2^31到2^31-1。要从字节数组转换为`Int32`,可以使用`BitConverter.ToInt32()`方法。这个方法接受字节数组和起始位置作为参数,并返回转换后的...
它的范围是从-2^31到2^31-1(即-2147483648到2147483647)。int类型的数据可以直接进行算术运算,如加减乘除等。 ### 二、String类型与int类型的比较 在Java中,直接比较一个String类型的值与一个int类型的值是...
整数型数据类型包括 bigint、int、smallint 和 tinyint 四种,分别对应 64 位、32 位、16 位和 8 位的整数。其中,bigint 型数据的存储大小为 8 个字节,数值范围是-2^63~2^63-1;int 型数据的存储大小为 4 个字节...
而`int`是32位的整数类型,其数值范围是-2^31到2^31-1,即-2,147,483,648到2,147,483,647。当尝试将一个`long`类型的值转换为`int`时,如果这个`long`值超出了`int`的表示范围,就会发生溢出。 ### 强制类型转换 这...
`dec2hex`函数默认将十进制整数转换为十六进制字符串,而`Int2Hex`函数特别针对64位有符号整数进行了优化和处理。在本文中,我们将深入探讨MATLAB中的数值表示、`dec2hex`函数的使用以及`Int2Hex`函数可能实现的特性...