c语言中int的用法

2016-12-02

C/C++编程语言中,int表示整型变量,是一种数据类型,用于定义一个整型变量,在不同编译环境有不同的大小,不同编译运行环境大小不同。下面小编就跟你们详细介绍下c语言中int的用法,希望对你们有用。

c语言中int的用法如下:

1. 整型int

C 语言提供了很多整数类型(整型),这些整型的区别在于它们的取值范围的大小,以及是否可以为负。int是整型之一,一般被称为整型。以后,在不产生歧义的情况下,我们把整数类型和int都称为整型。

int代表有符号整数,也就是说,用int声明的变量可以是正数,可以是负数,也可以是零,但是只能是整数。标准规定int的最小取值范围是 -32767 到 32767。int的取值范围因机器而异,但是一定要大于或者等于 -32767 到 32767。一般来说,int占用一个字的内存空间。因此,字长为 16 位(Bit)的旧式 IBM 兼容机使用 16 位来储存整型int,取值范围是

-32768 到 32767 。目前的个人电脑一般都是 32 位字长的,这些电脑中,int一般也是 32 位的,取值范围是 -2147483648 到 2147483647。对于使用 64 位 CPU 的电脑,使用更多位储存int也是很自然的事情,取值范围当然也会更大。

2. 声明int类型的变量

正如我们在以前的教程里看到的那样,int用于声明整型变量:以int打头,后面跟着变量的名字,最后以分号(;)结束。例如:

interns; /* 声明一个变量 */

/* 注意:一定要用逗号(,),不能用分号(;)*/

int hogs, cows, goats; /* 声明三个变量 */

以上声明创建了变量,但是没有给它们提供“值(value)”。在前面的教程中,我们已经用了两种方法使变量获得“值”。一种是赋值:cows = 500; 。另一种是使用scanf函数:scanf( "%d", &goats ); 。下面我们来学习第三种方法。

3. 初始化变量

初始化变量是指给变量赋初值:声明变量的时候,在变量名的后面写上等号(=),然后写下你希望赋予变量的“值”。例如:

int hogs = 21;

int cows = 32, goats = 14;

int dogs, cats = 94;

以上声明创建了变量,并且为这些变量分配了空间,同时也赋了初值。注意,第三行中只有 cats 被初始化为 94,而 dogs 没有被初始化!如下图:

4. int常量

上面的例子中,21、32、14,以及 94 都是整数常量。C 语言中,整数常量的默认类型是int。如果整数常量的大小超过了int的取值范围,那么编译器将会把这个整数常量当作 long int类型来处理,这个我们后面还会讲到。21、32、14 和 94 都在int的取值范围之内,因此它们都是int常量。

5. 输出int型数据

我们可以用printf函数来输出int型数据。正如我们在前面的教程中看到的那样,占位符 %d 代表输出的是int型数据,它告诉printf函数在什么地方输出相应的int型数据。%d 也被称为格式限定符(format specifier),因为它指定了printf函数应该使用什么形式来输出数据。printf函数的第一个参数只能是字符串,这个字符串被称为格式串(format string)。格式串中有多少个 %d,我们就应该相应地提供多少个int型参数给printf函数。int型参数可以是int型变量,int型常量,以及结果为int型的表达式等。例如:

int year = 2005; /* year 是int型变量 */

printf( "Today is %d-%d-%d ", year, 9, 20 + 9 ); /* 20 + 9 是加法表达式 */

保证格式限定符的数目和参数数目一致是我们的责任,编译器不负责捕捉这种错误!例如:

#include <stdio.h>

int main(void)

{

int ten = 10, two = 2;

printf("%d minus %d is %d ", ten ); /* 少写了两个参数 */

getchar(); /* 等待用户按回车 */

return 0;

}

这个程序可以通过编译,但是运行结果将会出乎意料,因为我们少写了两个参数。标准规定,如果格式限定符的数目大于参数数目,则printf函数的行为是未定义的;如果参数数目大于格式限定符的数目,则多余的参数会被忽略。

6. 八进制(octal)和十六进制(hexadecimal)

C 语言中,整数常量默认是十进制(decimal)整数。通过在整数常量前面加上特定的前缀,可以把它设定为八进制或者十六进制整数。前缀 0x 或者 0X 把整数常量设定为十六进制整数。注意,是数字 0 ,而不是字母 O ,别搞错了哦!例如:十进制的 16 用十六进制来表示是 0x10 或者 0X10 。在整数常量前面加上前缀 0 ,表示它是八进制整数。注意,是数字 0 ,而不是字母 O 。例如:十进制的 16 表示为八进制就是 020 。

7. 以八进制或者十六进制形式输出数据

使用格式限定符 %o 可以以八进制的形式输出整数。注意,是小写字母 o ,不是数字 0 。使用 %x 或者 %X 可以以十六进制的形式输出整数。小写 x 表示输出使用小写字母,大写 X 表示输出使用大写字母。使用 %#o,%#x 或者 %#X,得到的输出将包括前缀 0,0x 或者 0X。例如:

#include <stdio.h>

int main(void)

{

int x = 200;

printf("dec = %d; octal = %o; hex = %x; HEX = %X ", x, x, x, x);

printf("dec = %d; octal = %#o; hex = %#x; HEX = %#X ", x, x, x, x);

getchar();

return 0;

}

这个程序的输出是:

dec = 200; octal = 310; hex = c8; HEX = C8

dec = 200; octal = 0310; hex = 0xc8; HEX = 0XC8

1. 其它整数类型

int是 C 语言的基本整数类型,可以满足我们处理一般数据的需求。C 语言还提供了四个可以修饰int的关键字:short、long、signed,以及 unsigned。利用这四个关键字,C 语言标准定义了以下整数类型:

1) short int(可简写为 short),和int一样,也是有符号整数

2) long int(简写:long),有符号整数

3) long longint(简写:long long),C99 标准添加的类型,

有符号整数

4) unsigned int(简写:unsigned),无符号整数,不能表示负数

5) unsigned long int(简写:unsigned long),无符号整数,

不能表示负数

6) unsigned short int(简写:unsigned short),无符号整数,

不能表示负数

7) unsigned long longint(简写:unsigned long long),

C99 添加的类型,无符号整数

8) 所有没有标明 unsigned 的整数类型默认都是有符号整数。

在这些整数类型前面加上 signed 可以使读者更清楚地知道

这些是有符号整数,尽管有没有 signed 都表示有符号整数。

例如:signed int等同于int。

一般我们把 short 称为短整型,把 long 称为长整型,把 long long称为超长整型,把int称为整型。unsigned 打头的那些整数类型统称为无符号整型。例如:我们称 unsigned short 为无符号短整型。以此类推。

2. 声明方式

这些整数类型的声明方式与int类型的声明方式一样。例如:

longintestine;

long johns;

shortinterns;

short ribs;

unsignedints_count;

unsigned players;

unsigned long headcount;

unsigned short yesvotes;

long longago; /* C99 特有 */

unsigned long long ego; /* C99 特有 */

如果您的编译器不支持 C99 标准,那就不能使用 long long和 unsigned long long。

3. 取值范围(表示范围)

标准也规定了这些整数类型的最小取值范围。short 的最小表示范围和int一样,都是

-32767 到 32767 。也就是 -(2^15 - 1)到(2^15 - 1)。其中,2^15表示 2 的 15 次方。类似地,2 的 20 次方记作 2^20 ,以此类推。注意:C 语言中 2^15 并不表示 2 的 15 次方,为了书写方便,我们姑且这么表示。long 的最小取值范围是 -2147483647 到 2147483647 。也就是 -(2^31 - 1) 到 (2^31 - 1) 。unsigned short的最小表示范围和unsigned int一样,都是 0 到 65535(2^16 - 1)。unsigned long 的最小取值范围是 0 到 4294967295(2^32 - 1)。long long的最小取值范围是 -9223372036854775807(-(2^63 - 1))到 9223372036854775807(2^63 - 1);unsigned long long是 0 到 18446744073709551615(2^64 - 1)。

标准规定,int的表示范围不能小于 short 的表示范围,long 的表示范围不能小于int的表示范围。这就是说 short 型变量占用的空间可能比int型变量少,而 long 型变量占用的空间可能比int型变量多。16 位(bit)的计算机中,int和 short 一般都是 16 位,而 long 是 32位;32位的计算机中,short一般是 16 位,而long和int是 32位。TC2(16位的编译器)中,int是16位的;而Dev-C++(32 位的编译器)中,int是 32 位的。

使用 unsigned int声明的变量只能表示非负整数(0 和正整数)。如果int是 16 位的话,那么 unsigned int的表示范围是 0 到 65535(2^16 - 1)。这是因为 unsigned 不需要符号位,可以把 16 个位全都用于表示整数。而int需要一个位作为符号位,用于表示正负,只有 15 个位用于表示整数。

目前,long long一般 64 位,long 是 32 位,short 是 16 位,而int或者 16 位,或者 32 位。具体某个编译器到底使用多少位来表示这些类型,我们可以用运算符sizeof来获取。例如:

printf( "%lu ", (unsigned long)sizeof(int) * 8 ); /* 输出int的位数 */

printf( "%zu ", sizeof(short) * 8 ); /* 输出 short 的位数 */

sizeof运算符返回其操作数占用空间的大小,以字节(Byte)为单位。注意,C 定义字节的大小为 char 类型的大小。char 通常是 8 位(bit)的,当然也可以更大。这里我们假设 char 是 8 位的。点击查看 char 类型详细介绍

sizeof的用法我们以后会讲到,现在只要有个印象就好了。第二句中的 %zu是 C99 特有的,如果您的编译器不支持 C99(准确地说,应该是如果您的编译器使用的库函数不支持 C99),运行结果将会出错。

4. 整数类型的选择

如果您要处理的只是非负整数,那么应该优先使用 unsigned 打头的那些整数类型。如果您要处理的整数超出了int所能表示的范围,并且您的编译器中,long 的表示范围比int大,那就使用 long。不过,若非必要,尽量不要用 long,因为它可能会降低程序运行效率。有一点要注意:如果您的编译器中,long 和int都是 32 位的,并且您需要使用 32 位整数,那么应该用 long,而不要用int。只有这样,我们的程序才可以安全地移植到 16 位的计算机,因为 16 位的计算机中,int一般也是 16 位的。类似地,如果您需要使用 64 位整数,那就用 long long。如果int是 32 位的话,那么使用 short 可以节省空间,不过您得确保您要处理的整数不会超出 short 的表示范围。这种“节省”对内存大的计算机来说,是没什么意义的。

5. long 型常量和 long long型常量

一般来说,整数常量是被当作int类型来存储的。如果我们使用的整数常量超出了int的表示范围,C 语言规定编译器自动使用 unsigned int来处理这个常量。如果 unsigned 也不足以表示这个常量的话,编译器就会用 long。如果还表示不了的话,那就依次用 unsigned long,long long,unsigned long long。如果 unsigned long long也表示不了,那么编译器就没辙了。注意:long long和 unsigned long long是 C99 特有的。例如:如果int是 16 位的话,它就表示不了常量 1000000。编译器会使用 long 来处理这个常量,因为 unsigned int也表示不了 1000000 。

同样,十六进制和八进制整数常量通常也是被作为int来处理。但是,当我们使用的常量超出了int的表示范围后,编译器会依次使用unsigned int,long,unsigned long,long long和 unsigned long long。直到所使用的类型足以表示那个常量为止。

有时,我们使用的是较小的常量,但是我们希望这个常量被当作 long 来处理,这就需要在这个常量后面加上后缀 l(小写字母 l)或者 L(大写字母 L)。我们应该避免使用 l ,因为 l 容易和数字 1 混淆。例如:整数常量 7 是被作为int来处理的,但整数常量 7L(或者 7l)是被作为 long 来处理的。类似地,在整数常量后面加上后缀ll或者 LL ,这个常量就会被当作 long long来处理。例如:3LL 。如果想使用无符号整数常量的话,还要配合使用后缀 u 或者 U 。例如:2u,3U,4Lu,5ul,6LU,7LLU,8Ull,9uLL 。

这些后缀也可以用于十六进制和八进制整数常量。例如:020L,010LL,0x30uL,0x40ull 。

1. 输出各种整数类型的变量

输出不同类型的整数,需要使用不用的格式限定符。输出 unsigned int类型的整数,要用 %u 。输出 long ,要用 %ld;如果要以十六进制或者八进制形式输出,那就用 %lx(或者%lX)或者 %lo。注意:虽然整数常量的后缀使用大写或者小写英文字母都没关系,但是它们格式限定符必须使用小写!如果我们要输出 short 类型的整数,可以在 %d 中间加上前缀 h,也就是%hd;同理,%ho 和 %hx(或者 %hX)分别表示以八进制或十六进制形式输出。前缀 h 和 l 可以和 u 组合,表示输出无符号整数。例如:%lu表示输出 unsigned long 类型的整数;%hu表示输出unsigned short类型的整数。如果您的编译器支持C99,可以使用 %lld和 %llu分别表示输出 long long和 unsigned long long。下面我们来看一个输出各种类型整数的程序:

#include <stdio.h>

int main(void)

{

unsigned int un = 3000000000; /* 我使用的编译器int是 32 位的 */

short end = 200; /* 而 short 是 16 位的 */

long big = 65537;

printf("un = %u and not %d ", un, un);

printf("end = %hd and %d ", end, end);

printf("big = %ld and not %hd ", big, big);

printf("Press ENTER to quit...");

getchar();

return 0;

}

使用Dev-C++ 编译运行这个程序输出结果如下:

un = 3000000000 and not -1294967296

end = 200 and 200

big = 65537 and not 1

Press ENTER to quit...

这个程序表明,错误使用格式限定符会导致意想不到的输出。首先,错误使用 %d 来做无符号整型变量 un 的格式限定符,导致输出的是负数。这是因为我的计算机使用相同的二进制形式来表示 3000000000 和 -129496296 ,而计算机只认识二进制。所以,如果我们使用 %u 告诉printf输出无符号整数,输出的就是 3000000000;如果我们误用了 %d,那么输出的就是一个负数。不过,如果我们把代码中的 3000000000 改成 96 的话,输出就不会出现异常。因为 96 没有超出int的表示范围。

然后,对于第二个printf,无论我们使用 %hd还是 %d,输出的结果都是一样的。这是因为 C 语言标准规定,当 short 类型值传递给函数时,要自动转化成int类型值。之所以转化成int,是因为int被设计为计算机处理效率最高的整数类型。所以,对于 short 和int大小不同的计算机来说,把变量 end 转化成int类型再传递给函数,速度更快。如此说来,h 好像没有存在意义。其实不然。我们可以用 %hd来看看较大的整数类型被截断成 short 类型的时候会是什么样的。

而第三个printf,由于误用 %hd,导致输出是 1。这是因为,如果 long 是 32 位的话,65537 的二进制形式便是 0000 0000 0000 0001 0000 0000 0000 0001,而 %hd命令printf输出 short 类型的值,从而导致printf只处理 16 位数据(假设 short 是 16 位的),最终导致输出 1。

在前面的教程里,我们说过,保证格式限定符的数目和参数数目一致是我们的责任。同样,保证格式限定符的类型和参数类型一致也是我们的责任!正如上面所说的那样,错误使用格式限定符会导致意想不到的输出!标准规定,如果任意参数和与其对应的格式限定符类型不一致,则printf的行为是未定义的;如果格式限定符本身就是非法的,则printf的行为也是未定义的。

2. 整数溢出

首先请看以下程序:

#include <stdio.h>

int main(void)

{

/* 32 位int表示范围的上限和下限 */

int i = 2147483647, j = -2147483648;

unsignedint k = 4294967295, l = 0;

printf("%d %d %d %d ", i, i+1, j, j-1);

printf("%u %u %u %u %u ", k, k+1, k+2, l, l-1);

printf("Press ENTER to quit...");

getchar();

return 0;

}

使用Dev-C++ 编译运行这个程序输出结果如下:

2147483647 -2147483648 -2147483648 2147483647

4294967295 0 1 0 4294967295

Press ENTER to quit...

本例中,i+1 是负数,j-1 是正数,k+1 是 0,l-1 是 4294967295 。这是因为加减运算过后,它们的值超出了它们对应的那种整数类型的表示范围,我们把这种现象称为溢出。

unsigned int型变量的值如果超过了上限,就会返回 0,然后从 0 开始增大。如果低于下限,那么就会到达 unsigned 型的上限,然后从上限开始减小。就好像一个人绕着跑道跑步一样,绕了一圈,又返回出发点。一般,int型变量溢出的话,会变成负数,或者正数。

对于 unsigned 类型的整数,它们溢出时的情况一定和上面描述的一样,这是标准规定的。但是标准并没有规定有符号整数溢出时会出现什么情况。这里描述的有符号整数溢出时出现的情况是最常见的,但是在别的计算机,使用别的编译器,也可能出现不同的情况。

补码运算,答案满意再追100,3天内有效

悬赏分:50 | 解决时间:2009-2-5 08:56 | 提问者:lishen226 <//passport.baidu.com/?business&aid=6&un=lishen226>

X = 76, 则 [X]补 = ?

[X]补 = 80H, 则 X = ?

[X]补 = 98H,则 [X]补/2 = ?

X = 78, Y = -83, 则 [X+Y]补 = ?

问题补充:

我教朋友计算机呢,遇到这几个题,都是N年前学的,都忘光了,最好有个解题步骤,谢谢了!最好能附上补码原码转换的一些知识点,比如负数怎么处理。

最佳答案

对正数而言: [X]原 = [X]反 = [X]补

对负数而言: [X]反 = [X]原 符号位不变,尾数按位变反。

[X]补 = [X]反 末位加“1”,

或[X]补 = [X]原 符号位不变,尾数按位变反后再加“1”。

[X]原 = [X]反 符号位不变,尾数按位变反。

[X]原 = [[X]补]补 即补码的补码,也就是说对负数的补码再求补得到原码。

X = 76 (都用一个字节表示)

则 [X]补 = [X]原 = 01001100B

[X]补 = 80H

这是补码的一个特殊情况-128,八位原码和反码都是表示不了这个数的。

[X]补 = (10000000)B 按位取反加1后有溢出,但计算机中该补码认定为-128,因此 X = -(10000000)B = -128

[X]补 = 98H

[X]补 = (10011000)B

如果计算机内做除以2的操作,因为计算机本身是将整个码当二进制数对待的,并不区分是什么码(也就是说计算机只认二进制数),所以 [X]补/2 是将[X]补 每位都算术右移一位(包括符号位)。 [X]补/2 = (01001100)B = 4CH。

如果是单求补码值的一半(除2),则可理解为符号位保持不变的算术右移一位,[X]补/2 = (11001100)B = CCH。

X = 78, Y = -83

[X]补 = (01001110)B

[Y]补 = (10101101)B

[X+Y]补 = [X]补 + [Y]补 = (01001110)B + (10101101)B = (11111011)B = FBH

·补码

<//pic2.itiexue.net/pics/2009_10_23_71497_10171497.gif>

[ 转自铁血社区 //bbs.tiexue.net/ ]

补码举例

补码(two's complement)

1、在计算机系统中,数值一律用补码来表示(存储)。

主要原因:使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补

码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。

2、补码与原码的转换过程几乎是相同的。

[ 转自铁血社区 //bbs.tiexue.net/ ]

求给定数值的补码表示分以下两种情况:

(1)正数的补码:与原码相同。

[例1]+9的补码是00001001。

(2)负数的补码:符号位为1,其余位为该数绝对值的原码按位取反;然后整个数加1。

[例2]求-7的补码。

因为给定数是负数,则符号位为“1”。

[ 转自铁血社区 //bbs.tiexue.net/ ]

后七位:+7的原码(0000111)→按位取反(1111000)→加1(1111001)

所以-7的补码是11111001。

已知一个数的补码,求原码的操作分两种情况:

(1)如果补码的符号位为“0”,表示是一个正数,其原码就是补码。

(2)如果补码的符号位为“1”,表示是一个负数,那么求给定的这个补码的补码就是要求的原码。

[例3]已知一个补码为11111001,则原码是10000111(-7)。

[ 转自铁血社区 //bbs.tiexue.net/ ]

因为符号位为“1”,表示是一个负数,所以该位不变,仍为“1”。

其余七位1111001取反后为0000110;

再加1,所以是10000111。

在“闲扯原码、反码、补码”文件中,没有提到一个很重要的概念“模”。我在这里稍微介绍一下“模”

的概念:

“模”是指一个计量系统的计数范围。如时钟等。计算机也可以看成一个计量机器,它也有一个计量范

[ 转自铁血社区 //bbs.tiexue.net/ ]

围,即都存在一个“模”。例如:

时钟的计量范围是0~11,模=12。

表示n位的计算机计量范围是0~2^(n)-1,模=2^(n)。

“模”实质上是计量器产生“溢出”的量,它的值在计量器上表示不出来,计量器上只能表示出模的

余数。任何有模的计量器,均可化减法为加法运算。

例如: 假设当前时针指向10点,而准确时间是6点,调整时间可有以下两种拨法:

[ 转自铁血社区 //bbs.tiexue.net/ ]

一种是倒拨4小时 <//data.tiexue.net/person/xiaoshi18327/>,即:10-4=6

另一种是顺拨8小时 <//data.tiexue.net/person/xiaoshi18327/>:10+8=12+6=6

在以12模的系统中,加8和减4效果是一样的,因此凡是减4运算,都可以用加8来代替。

对“模”而言,8和4互为补数。实际上以12模的系统中,11和1,10和2,9和3,7和5,6和6都有这个特

性。共同的特点是两者相加等于模。

对于计算机,其概念和方法完全一样。n位计算机,设n=8, 所能表示的最大数是11111111,若再

[ 转自铁血社区 //bbs.tiexue.net/ ]

加1称为100000000(9位),但因只有8位,最高位1自然丢失。又回了00000000,所以8位二进制系统的

模为2^8。 在这样的系统中减法问题也可以化成加法问题,只需把减数用相应的补数表示就可以

了。把补数用到计算机对数的处理上,就是补码。

另外两个概念

一的补码(one's complement) 指的是正数=原码,负数=反码

而二的补码(two's complement) 指的就是通常所指的补码。

[ 转自铁血社区 //bbs.tiexue.net/ ]

3.补码的绝对值(称为真值)

[例4]-65的补码是10111111

若直接将10111111转换成十进制,发现结果并不是-65,而是191。

事实上,在计算机内,如果是一个二进制数,其最左边的位是1,则我们可以判定它为负数,并且是用补码表示。

若要得到一个负二进制数的绝对值(称为真值),只要各位(包括符号位)取反,再加1,就得到真值。

如:二进制值:10111111(-65的补码)

[ 转自铁血社区 //bbs.tiexue.net/ ]

各位取反:01000000

加1:01000001(+65的补码)

这里补充补码的代数加减运算:

1、补码加法

[X+Y]补 = [X]补 + [Y]补

[例5]X=+0110011,Y=-0101001,求[X+Y]补

[ 转自铁血社区 //bbs.tiexue.net/ ]

[X]补=00110011 [Y]补=11010111

[X+Y]补 = [X]补 + [Y]补 = 00110011+11010111=00001010

注:因为计算机中运算器的位长是固定的,上述运算中产生的最高位进位将丢掉,所以结果不是

100001010,而是00001010。

2、补码减法

[X-Y]补 = [X]补 - [Y]补 = [X]补 + [-Y]补

[ 转自铁血社区 //bbs.tiexue.net/ ]

其中[-Y]补称为负补,求负补的方法是:所有位(包括符号位)按位取反;然后整个数加1。

[例6]1+(-1) [十进制]

1的原码00000001 转换成补码:00000001

-1的原码10000001 转换成补码:11111111

1+(-1)=0

00000001+111111111=00000000

[ 转自铁血社区 //bbs.tiexue.net/ ]

00000000转换成十进制为0

0=0所以运算正确。

这里补充补码的代数解释:

任何一个数都可以表示为-a=2^(n-1)-2^(n-1)-a;

这个假设a为正数,那么-a就是负数。而根据二进制转十进制数的方法,我们可以把a表示为:a=k0*2^0+k1*2^1+k2*2^2+……+k(n-2)*2^(n-2)

这里k0,k1,k2,k(n-2)是1或者0,而且这里设a的二进制位数为n位,即其模为2^(n-1),而2^(n-1)其二项展开是:1+2^0+2^1+2^2+……+2^(n-2),而式子:-a=2^(n-1)-2^(n-1)-a中,2^(n-1)-a代入a=k0*2^0+k1*2^1+k2*2^2+……+k(n-2)*2^(n-2)和2^(n-1)=1+2^0+2^1+2^2+……+2^(n-2)两式,2^(n-1)-a=(1-k(n-2))*2^(n-2)+(1-k(n-3))*2^(n-3)+……+(1-k2)*2^2+(1-k1)*2^1+(1-k0)*2^0+1,而这步转化正是取反再加1的规则的代数原理所在。因为这里k0,k1,k2,k3……不是0就是1,所以1-k0,1-k1,1-k2的运算就是二进制下的取反,而为什么要加1,追溯起来就是2^(n-1)的二项展开式最后还有一项1的缘故。而-a=2^(n-1)-2^(n-1)-a中,还有-2^(n-1)这项未解释,这项就是补码里首位的1,首位1在转化为十进制时要乘上2^(n-1),这正是n位二进制的模。

[ 转自铁血社区 //bbs.tiexue.net/ ]

不能贴公式,所以看起来很麻烦,如果写成代数式子看起来是很方便的。

注:n位二进制,最高位为符号位,因此表示的数值范围-2^(n-1) --2^(n-1) -1,所以模为2^(n-1)。上面提到的8位二进制模为2^8是因为最高位非符号位,表示的数值范围为0--2^8-1。

·[转]

原码表示法是机器数的一种简单的表示法。其符号位用0表示正号,用:表示负号,数值一般用二进制形式表示。设有一数为x,则原码表示可记作〔x〕原。

[ 转自铁血社区 //bbs.tiexue.net/ ]

例如,X1= +1010110

X2= 一1001010

其原码记作:

〔X1〕原=[+1010110]原=01010110

〔X2〕原=[-1001010]原=11001010

原码表示数的范围与二进制位数有关。当用8位二进制来表示小数原码时,其表示范围:

[ 转自铁血社区 //bbs.tiexue.net/ ]

最大值为0.1111111,其真值约为(0.99)10

最小值为1.1111111,其真值约为(一0.99)10

当用8位二进制来表示整数原码时,其表示范围:

最大值为01111111,其真值为(127)10

最小值为11111111,其真值为(-127)10

在原码表示法中,对0有两种表示形式:

[ 转自铁血社区 //bbs.tiexue.net/ ]

〔+0〕原=00000000

[-0] 原=10000000

(2)补码表示法

机器数的补码可由原码得到。如果机器数是正数,则该机器数的补码与原码一样;如果机器数是负数,则该机器数的补码是对它的原码(除符号位外)各位取反,并在未位加1而得到的。设有一数X,则X的补码表示记作〔X〕补。

例如,[X1]=+1010110

[X2]= 一1001010

[ 转自铁血社区 //bbs.tiexue.net/ ]

[X1]原=01010110

[X1]补=01010110

即 [X1]原=[X1]补=01010110

[X2] 原= 11001010

[X2] 补=10110101+1=10110110

补码表示数的范围与二进制位数有关。当采用8位二进制表示时,小数补码的表示范围:

[ 转自铁血社区 //bbs.tiexue.net/ ]

最大为0.1111111,其真值为(0.99)10

最小为1.0000000,其真值为(一1)10

采用8位二进制表示时,整数补码的表示范围:

最大为01111111,其真值为(127)10

最小为10000000,其真值为(一128)10

在补码表示法中,0只有一种表示形式:

[ 转自铁血社区 //bbs.tiexue.net/ ]

[+0]补=00000000

[+0]补=11111111+1=00000000(由于受设备字长的限制,最后的进位丢失)

所以有[+0]补=[+0]补=00000000

(3)反码表示法

机器数的反码可由原码得到。如果机器数是正数,则该机器数的反码与原码一样;如果机器数是负数,则该机器数的反码是对它的原码(符号位除外)各位取反而得到的。设有一数X,则X的反码表示记作〔X〕反。

例如:X1= +1010110

[ 转自铁血社区 //bbs.tiexue.net/ ]

X2= 一1001010

〔X1〕原=01010110

[X1]反=〔X1〕原=01010110

[X2]原=11001010

[X2]反=10110101

反码通常作为求补过程的中间形式,即在一个负数的反码的未位上加1,就得到了该负数的补码。

[ 转自铁血社区 //bbs.tiexue.net/ ]

例1. 已知[X]原=10011010,求[X]补。

分析如下:

由[X]原求[X]补的原则是:若机器数为正数,则[X]原=[X]补;若机器数为负数,则该机器数的补码可对它的原码(符号位除外)所有位求反,再在未位加1而得到。现给定的机器数为负数,故有[X]补=[X]原十1,即

[X]原=10011010

[X]反=11100101

十) 1

[ 转自铁血社区 //bbs.tiexue.net/ ]

[X]补=11100110

例2. 已知[X]补=11100110,求〔X〕原。

分析如下:

对于机器数为正数,则〔X〕原=〔X〕补

对于机器数为负数,则有〔X〕原=〔〔X〕补〕补

现给定的为负数,故有:

[ 转自铁血社区 //bbs.tiexue.net/ ]

〔X〕补=11100110

〔〔X〕补〕反=10011001

十) 1

〔〔X〕补〕补=10011010=〔X〕原

更多相关阅读

最新发布的文章