精华内容
下载资源
问答
  • 计算机中的信息表示

    2021-02-19 07:45:56
    一个数无论采用哪种进位制表示,都跑含个基本要素:基数和位权。 基数:任何一进制允许选用基本数字符号个数叫做基数。 位权:一个数字符号出现在数中不同数位上,其代表数值是不同。一个数字符号所...

    计算机中的信息表示

    在计算机中信息可以分为两大类:数据信息和控制指令信息。

    1. 进位计数制及其转换

    进位计数制,就是人们利用数字符号来计数的方法。进位计数制有很多种,计算机中常用二进制、十进制、十六进制。一个数无论采用哪种进位制表示,都跑含两个基本要素:基数和位权。

    基数:任何一种进制允许选用的基本数字符号的个数叫做基数。

    位权:一个数字符号出现在数中的不同数位上,其代表的数值是不同的。一个数字符号所表示的数值就等于该数字乘以一个与它所在数位有关的常数,这个常数就做位权。

    1. 进位计数制之间的转换

    二进制转为十进制:101.1=1*2^2+0*2^1+1*2^0+1*2^-1=5.5。

    八进制转为十进制:5.4=5*8^0+4*8^-1=5.5

    十六进制转为十进制:5.8=5*16^0+8*16^-1=5.5

     

     

    方法:用每一个数码位乘以位权。

    1. 二进制转为八进制,十六进制

    如八进制,它的基数是八,每个数码位有八种情况,

    二进制,他的基数是2,每三位二级制则对应八进制一位数。

     

    二进制转八进制:三位一组,每组转换成对应的八进制符号。

    例如:1111000010.01101=1702.32

     

     

     

     

    十进制转换为二进制:采用整数用除2取余,小数用乘2取整

    如75.3=1001011.01001

     

     

     

     

    1. 无符号数和带符号数的表示

    无符号数:整个机器字长的全部二进制位均表示数值位(没有符号位),相当于数的绝对值。

    例如:x1=01001,表示无符号数9

    无符号数范围0-255

    1. 带符号数的表示

    原码:用尾数表示真值的绝对值,符号位0表示正,1表示负。

    例如: 

    补码:正数的补码=原码

          负数的补码=反码末位+1(考虑进位)

    例如:  

    移码:补码的基础上将符号取反。注意移码只能用来表示整数。

    例如: 

     

    1. 十进制数的编码

    BCD码:在BCD码中,每一位十进制数都用4位二进制编码表示。

      

     

    展开全文
  • 计算机中信息的表示与存储

    千次阅读 2005-02-24 10:39:00
    1.3 计算机中信息的表示与存储计算机的基本功能是对数据进行运算和加工处理。数据有两种,一种是数值数据,如3.1416、-2.71828……,另一种是非数值数据(信息),如A、b、+、=……。无论一种数据在计算机中都是...

    1.3 计算机中信息的表示与存储

    计算机的基本功能是对数据进行运算和加工处理。数据有两种,一种是数值数据,如3.1416-2.71828……,另一种是非数值数据(信息),如Ab、+、=……。无论哪一种数据在计算机中都是用二进制数码表示的。计算机中只有二进制数值,所有的符号都是用二进制数值代码表示的,数的正、负号也是用二进制代码表示。数值的最高位用“0”、“1”分别表示数的正、负号。一个数(连同符号)在计算机中的表示形式称为机器数,数值处理采用二进制运算,非数值处理采用二进制编码,它们具有运算简单、电路实现方便、成本低廉等优点。

    1.3.1 进位计数制

    一种进位计数制包含一组数码符号和两个基本因素:

    数码 一组用来表示某种数制的符号。如:123AB

    基数 数制所用的数码个数,用R表示,称R进制,其进位规律是“逢R进一”。如:十进制的基数是10 101

    位权 数码在不同位置上的权值。在某进位制中,处于不同数位的数码,代表不同的数值,某一个数位的数值是由这位数码的值乘上这个位置的固定常数构成,这个固定常数称为“位权”。如:十进制的个位的位权是“1”,百位的位权是“100”。

    一、十进制

    十进制数,它的数码是用10个不同的数字符号01、…… 89来表示的。由于它有10个数码,因此基数为10。数码处于不同的位置表示的大小是不同的,如3468.795这个数中的4就表示4×102400,这里把10n称作位权,简称为“权”,十进制数又可以表示成按“权”展开的多项式。例如:3468.7953×1034×1026×1018×1007×10-1+9×10-2+5×10-3

    十进制数的运算规则是:逢101

    二、二进制

    计算机中的数据是以二进制形式存放的,二进制数的数码是用01来表示的。二进制的基数为2,权为2n,二进制数的运算规则是:逢21

    对于一个二进制数,也可以表示成按权展开的多项式。例如:

    10110.101=1×240×231×221×210×201×2-10×2-21×2-3

    三、八进制和十六进制

    八进制数的数码是用01、…… 67来表示的。八进制数基数为8,权为8n,八进制数的运算规则是:逢81

    十六进制数的数码是用01、…… 9ABCDEF来表示的。十六进制数的基为16,权为16n,十六进制数的运算规则是:逢161

    其中符号A对应十进制中的10B表示11,……,F表示十进制中的15

    在书写时,可用以下3种格式:

    如第1种:111 011012331835.8110FA516

    如第2种:(10110.0112,(7558,(13910,(AD616

    如第3种:10101.001B 761O 3762D 2CE6H

    这里字母BODH分别表示二进制、八进制、十进制和十六进制。

    1.3.2 数制之间的转换

    一、二进制数、八进制数、十六进制数转换为十进制数

    各种进制的数按权展开后求得结果即为十进制数。

    1.1 将二进制数(1011.1012转换成等值的十进制数。

    1011.1012 = 1×23+0×22+1×21+1×20 +1×2-1 + 0×2-2+1×2-3

    = 8 + 0 + 2 + 1 +1/2 + 0 +1/8

    =(11.625)10

    八进制数和十六进制数均可按位权展开转换成十进制数。

    1.2 将(25768、(3D.B16分别转换成十进制数。

    257682×83+5×827×816×80=(140610

    3D.B163×16113×16011×161=(61.687510

    二、十进制数转换为二进制数

    对于十进制数的整数部分和小数部分在转换时须作不同的计算,分别求得后再组合。

    1. 十进制整数转换为二进制数(除2取余法)

    方法:逐次除以2,每次求得的余数即为二进制数整数部分各位的数码,直到商为0

    2. 十进制纯小数转换为二进制数(乘2取整法)

    方法:逐次乘以2,每次乘积的整数部分即为二进制数小数各位的数码。

    1.3 把十进制数69.8125转换为二进制数。

    1-4.gif

    图1.4 十进制数转换为二进制数

    对整数部分69转换,如图1.4左图所示,得:(6910=(10001012

    将小数0.8125转换为二进制小数,如图1.4右图所示,得:(0.812510=(0.11012

    因此69.8125D=1000101.1101B

    十进制数转换成八进制数和十六进制数也可用上述方法进行。

    3.二进制数与八进制数的互相转换

    1)二进制数转换成八进制数

    二进制数转换成八进制数的方法是:将二进制数从小数点开始分别向左(整数部分)和向右(小数部分)每3位二进制数码分成一组,转换成八进制数码中的一个数字,连接起来。不足3位时,对原数值用0补足3位。

    1.4 把二进制数(11110010.11100112转换为八进制数。

    二进制3位分组:

    011

    110

    010

    .

    111

    001

    100

    转换成八进制数:

    3

    6

    2

    .

    7

    1

    4

    11110010.11100112=(362.7148

    2)八进制数转换成二进制数

    八进制数转换成二进制数的方法是:将每一位八进制数写成相应的3位二进制数,再按顺序排列好。

    1.5 把八进制数(2376.148转换为二进制数。

    八进制1

    2

    3

    7

    6

    .

    1

    4

    二进制3

    010

    011

    111

    110

    .

    001

    100

    2376.148=(10011111110.00112

    4.二进制数与十六进制数的互相转换

    二进制数与十六进制数的转换方法:和二进制数与八进制数的转换方法类似,是将4位二进制数码为一组对应成1位十六进制数,而十六进制数与二进制数的转换是将十六进制数的1位与二进制数的4位数相对应,再按顺序排列好。

    1.6 把二进制数(110101011101001.0112转换为十六进制数。

    二进制4位分组:

    0110

    1010

    1110

    1001

    .

    0110

     

    转换成十六进制数:

    6

    A

    E

    9

    .

    6

     

    (110101011101001.011)2=(6AE9.6)16

    在这里我们看到二进制和八进制、十六进制之间的转换非常直观,因此,要把一个十进数转换成二进制数可以先转换为八进制数或十六进制数,然后再快速地转换成二进制数。

    同样,在转换中若要将十进制数转换为八进制数和十六进制数时。也可以先把十进制数转换成二进制数,然后再转换为八进制数或十六进制数,如表1.1所示为常用计数制对照表。

    例如将十进制数673转换为二进制数,可以先转换成八进制数(除以8求余法)得1241,再按每位八进数转为3位二进数,求得1010100001B,如还要转换成十六进制数用4位一组很快就能得到2A1H

    1.1 常用计数制对照表

    十进制数

    二进制数

    八进制数

    十六进制数

    0

    0

    0

    0

    1

    1

    1

    1

    2

    10

    2

    2

    3

    11

    3

    3

    4

    100

    4

    4

    5

    101

    5

    5

    6

    110

    6

    6

    7

    111

    7

    7

    8

    1000

    10

    8

    9

    1001

    11

    9

    10

    1010

    12

    A

    11

    1011

    13

    B

    12

    1100

    14

    C

    13

    1101

    15

    D

    14

    1110

    16

    E

    15

    1111

    17

    F

    16

    10000

    20

    10

    1.3.3 二进制数的运算

    在计算机中,二进制数可作算术运算和逻辑运算。

    一、算术运算

    加法:000 10011 1110

    减法:0-00 10-11 1-01 1-10

    乘法:0×00 0×11×00 1×11

    除法:0/10 1/11

    二、逻辑运算

    1.或:“∨”、“+”

    000 011 101 111

    或运算中,当两个逻辑值只要有一个为1时,结果为1,否则为0

    1.7 要判断成绩X是否处在小于60或者成绩Y是否处在大于95的分数段中,可这样表示:(X<60)∨(Y>95

    X=70Y=88时,这时X<60Y>95条件都不满足,两个表达式结果均为0,“∨”运算结果为0

    X小于60,则X<60的表达式满足为1,而无论Y取何值,这时“∨”运算结果为1

    同样只要Y大于95分,而无论X取何值,这时“∨”运算结果为1

    如果X=50Y=98,这时X<60满足(为1),Y>95亦满足(为1),“∨”运算结果为1

    2.与:“∧”、“·”

    000 010 100 111

    与运算中,当两个逻辑值都为1时,结果为1,否则为0

    1.8 一批合格产品的标准需控制在205~380之间,要判断某一产品质量参数X是否合格,可用这样表示:(X>205)∧(X<380

    X的值不在该区间内时,X>205X<380条件中至少有一个条件不满足(“∧”运算规则中的前3种情况),“∧”结果为0,产品为不合格。

    X的值在该区间内时,X>205X<380条件同时满足都为1,“∧”结果为1

    3.非:“ˉ”

    非运算中,对每位的逻辑值取反。

    规则:Image75.gifImage76.gif

    1.9 Image77.gif

    1.10 若用1表示性别为男,则 Image843.gif表示女。

    4.异或:“Image84.gif

    0 Image84.gif 0=0 0 Image84.gif 1=1 1 Image84.gif 0=1 1 Image84.gif 1=0

    异或运算中,当两个逻辑值不相同时,结果为1,否则为0。

    1.3.4 非数值信息的表示

    一、ASCII

    ASCII码(American Standard Code for Information Interchange)是美国信息交换标准代码的简称。ASCII码占一个字节,有7ASCII码和8ASCII码两种,7ASCII码称为标准ASCII码,8ASCII码称为扩充ASCII码。7位二进制数给出了128个不同的组合,表示了128个不同的字符。其中95个字符可以显示,包括大小写英文字母、数字、运算符号、标点符号等。另外的33个字符,是不可显示的,它们是控制码,编码值为031127。例如回车符(CR),编码为13,如表1.2ASCII码字符编码表。

    1.2 ASCII码字符编码表

    b6 b5 b4

    b3 b2 b1 b0

    000

    001

    010

    011

    100

    101

    110

    111

    0 0 0 0

    NUL

    DLE

    SP

    0

    @

    P

    `

    p

    0 0 0 1

    SOH

    DC1

    !

    1

    A

    Q

    a

    q

    0 0 1 0

    STX

    DC2

    "

    2

    B

    R

    b

    r

    0 0 1 1

    ETX

    DC3

    #

    3

    C

    S

    c

    s

    0 1 0 0

    EOT

    DC4

    $

    4

    D

    T

    d

    t

    0 1 0 1

    ENQ

    NAK

    %

    5

    E

    U

    e

    u

    0 1 1 0

    ACK

    SYN

    &

    6

    F

    V

    f

    v

    0 1 1 1

    BEL

    ETB

    '

    7

    G

    W

    g

    w

    1 0 0 0

    BS

    CAN

    8

    H

    X

    h

    x

    1 0 0 1

    HT

    EM

    9

    I

    Y

    i

    y

    1 0 1 0

    LF

    SUB

    *

    :

    J

    Z

    j

    z

    1 0 1 1

    VT

    ESC

    +

    ;

    K

    [

    k

    {

    1 1 0 0

    FF

    FS

    <

    L

    /

    l

    |

    1 1 0 1

    CR

    GS

    -

    =

    M

    ]

    m

    }

    1 1 1 0

    SO

    RS

    .

    >

    N

    ^

    n

    ~

    1 1 1 1

    SI

    US

    /

    O

    _

    o

    DEL

    二、BCD码

    BCD码用4位二进制数表示一位十进制数,例如:BCD码1000 0010 0110 1001按4位一组分别转换,结果是十进制数8269,一位BCD码中的4位二进制代码都是有权的,从左到右按高位到低位依次权是8、4、2、1,这种二——十进制编码是一种有权码。1位BCD码最小数是0000,最大数是1001。

    1.3.5 汉字信息的基础

    要让计算机能进行汉字信息处理,必须解决汉字信息的输入、储存、输出和编码转换等问题。

    计算机处理汉字的基本过程如图1.5所示。用户用键盘输入的汉字编码,通过代码转换程序转换成汉字机内码进行储存、处理、加工,转换时要利用输入码到码表中去检索机内码。输出时,再利用字形检索程序在汉字字模库中查到表示这个汉字的字形码,根据字形码在显示器或打印机上输出。

    1-5.gif

    图1.5 汉字处理过程

    一、汉字编码

    如前所述,计算机对字母和符号采用国际上通用的ASCII码来编码。标准的ASCII码用7位二进制数编码,字符存放时采用一个字节,规定最高位为0,这样可以表示128个字符。同样,计算机对汉字也有一个编码问题。

    计算机通过包含汉字在内的字符集与用户进行信息交换,这些信息由计算机处理时,首先要把它变成计算机能接受的代码形式,最终计算机处理的信息又必须将内部代码形式转换成汉字的字形,才能被用户所理解。

    1GB2312-80

    20世纪70年代末,我国已认识到统一汉字编码对计算机中文信息的发展十分重要,为适应计算机信息处理技术发展的需要,1980年颁布了《信息交换用汉字编码字符集基本集》(国家标准代号为GB2312-80)。

    GB2312-80中共收录了汉字6763个,各种字母符号682个,合计7445个。这些汉字根据其常用程度又分为一级汉字、二级汉字。一级常用汉字3755个,以拼音为序,约占近代文献汉字累计使用频度99.9%左右;二级汉字3008个,以偏旁部首为序。一级、二级汉字约占累计使用频度99.99%以上。

    国标码以94个可显示的ASCII码字符为基集,采用双字节对汉字和符号进行编码,即用连续的两个字节表示一个汉字的编码。为了和ASCII区别,规定每个字节的最高位均为1。国标码与ASCII码属于同一制式,可以认为国标码是扩展的ASCII码。目前我国使用的汉字编码就是采用这个标准。

    GB2312-80规定,所有的国标汉字与符号组成一个94×94的矩阵。矩阵中的每一行称为一个“区”,每一列称为一个“位”。因此共有94个区(区号:01~94),每区94个位(位号:01~94)。 

    一个汉字所在的区号和位号简单地组合在一起就构成了该汉字的“国标区位码”。在连续的两个字节中,高位字节为区号,低位字节为位号。其汉字和符号在94×94矩阵中分布如图1.6所示,即区位码的编码范围是:0101~9494。例如,1区的33位是符号“×”,则输入“×”可用区位码0133。41区的29位是汉字“山”,则输入“山”可用区位码4129。

     

    1-6.gif

    图1.6 汉字编码区位分布图

    2.汉字机内码

    计算机系统中用来表示中文或西文信息的代码称为机内码,简称内码。ASCII码是一种西文机内码,用一个字节表示。汉字机内码用连续两个字节表示,每个字节的最高位是1。

    GB2312-80的内码编码的范围为:A1A1H~FEFEH。汉字机内码与区位码的关系为:

    汉字机内码高位字节=区位码高位字节+A0H

    汉字机内码低位字节=区位码低位字节+A0H

    例如,“×”的区位码是0133,则:

    高字节:(01)10+(A0)16=(01)16+(A0)16=(A1)16

    低字节:(33)10+(A0)16=(21)16+(A0)16=(C1)16

    则“×”的内码为A1C1。

    又如,“山”的区位码是4129,则:

    高字节:(41)10+(A0)16 =(29)16+(A0)16=(C9)16

    低字节:(29)10+(A0)16=(1D)16+(A0)16=(BD)16

    则“山”的内码为C9BD。

    Windows 2000内置的内码输入法支持区位码、GBK内码、UNICODE码的输入。用户可以在区位码的输入状态下,输入内码。即在区位码状态下,输入0133和A1C1都出现符号“×”。

    GBK是汉字扩展内码规范,GBK的目的是解决汉字收字不足、简繁同平面共存、简化代码体系间转换等汉字信息交换的瓶颈问题,它与GB2312-80内码体系完全兼容,并向最终的国际统一双字节字符集标准ISO10646.1迈进。用户可以使用“全拼”输入GBK中的汉字,采用“全拼”输入法输入汉字时,只要在切换到“全拼”输入状态后,用小写字母输入拼音原样。例如要输入“俶”字,它在“标准”或“五笔字型”输入法中均不能输入,但在“全拼”中只要输入chu,再翻几页就可以找到。需要说明的是,该汉字因为不属于GB2312-80,故不能以仿宋体及楷体等字体显示,但可以用宋体、黑体、隶书等字体显示。

    二、汉字输入码

    汉字输入方法一般有两种实现途径:一是由计算机自动识别汉字,要求计算机模拟人的智能;二是由人来完成识别工作,将相应的计算机编码以手动方式用键盘输入计算机。

    自动识别主要有3种方法:

    一是利用汉字识别技术,通过特殊的手写笔在感应板上书写汉字进行输入;二是利用语音识别技术,通过声音输入汉字;三是扫描识别输入,即把印在纸上或写在纸上的汉字通过扫描仪输入计算机,再用相应的软件将输入的信息转换成汉字机内码。下面主要介绍键盘输入方法。

    计算机用的标准键盘只有几十个键,而汉字至少有数千个,因此用键盘输入汉字,需对汉字进行编码。从20世纪80年代开始,到目前已经有数百种汉字输入编码方案产生,如区位码、全拼、五笔字型、微软拼音、智能ABC等,它们属于外码。

    按照编码原理,汉字输入码主要分为4类:顺序码(无重码)、音码、形码和以汉字的音、形相结合的音形码或形音码。

    顺序码是将GB2312-80中的所有汉字按一定顺序排列起来,予以编码,如区位码、国标码、电报码,它们无重码。音码是指采用汉语拼音的编码方式,常见的有智能ABC、微软拼音、全拼、简拼、双拼等。形码是采用汉字字形(如偏旁、字根)来编码的,如五笔字型、五笔划等。音形码是结合汉字的拼音和字形产生的编码,如自然码。

    三、汉字字库

    汉字信息存储在计算机内采用机内码,但输出时必须转换成字形码,以人们熟悉的汉字形式输出才有意义。因此对每一个汉字,都要有对应的字的模型(简称字模)储存在计算机内,字模的集合就构成了字模库,简称字库。汉字输出时,需要先根据内码找到字库中对应的字模,再根据字模输出汉字。

    构造汉字字形有两种方法:向量(矢量)法和点阵法。

    向量法是将汉字分解成笔画,每种笔画使用一段段的直线(向量)近似地表示,这样每个字形都可以变成一连串的向量。

    1.3.ht3.gif

    图1.7 用点阵组成的汉字字形

    点阵方式又称“字模点阵码”。每一个汉字以点阵形式存储在记录介质上,有点的地方为“1”,空白的地方为“0”。例如,可以将“杭”字画在图1.7所示的16×16的方格上,则“杭”字的字形码是00010000100000001000001000000、……0001000000000000。每一行为16位,共16行组成一个汉字的字形码,即共需要二进制位16×16=256位,等于32字节。

    汉字的表示也可以采用24×24点阵,此时表示一个汉字,需要24×24÷8=72个字节。点阵规模越大,每个汉字存储的字节数就越多,字库也就越庞大。但字形分辨率越好,字形也越美观。

    大多数汉字信息处理系统把汉字字库存放在磁盘上,这样的字库称为“软字库”,使用时全部或部分调入内存储器,并通过专门的软件实现从汉字机内码转变为对应的汉字字模点阵码的地址,根据地址找到相应的字形码。

    相对于“软字库”,一般将固化在EPROMMASK-ROM的芯片中的汉字字库称为“硬字库”。一般打印机等设备中都安装有带有固化汉字库的集成电路芯片,以提高输出汉字的速度。

    展开全文
  • 右移位运算分为两种, 逻辑右移和算术右移, 逻辑右移是指右移K位, 左端补上K个0, 而算术右移是指左端补上Kx3(最高有效位). 实际上, C语言标准并没有明确定义应该使用种类型右移. 对于无符号数, 右移必须是...

    2.1.10 C语言中的移位运算

    对于x = [x3, x2, x1, x0], x << 2 得到的结果是 [x1, x0, 0, 0]. 右移位运算分为两种, 逻辑右移和算术右移, 逻辑右移是指右移K位, 左端补上K个0, 而算术右移是指左端补上K的x3(最高有效位).

    实际上, C语言标准并没有明确定义应该使用哪种类型的右移. 对于无符号数, 右移必须是逻辑的, 对于有符号数则存在争议. (但事实上几乎所以的编译器/ 机器组合都会对有符号数据使用算术右移.)

    当移位数量足够大时 : 比如 w >> k, w是32位数, 而k恰好大于或等于32, 其实结果是未定义的(C语言标准并没有对这种情况进行规定)... 许多机器上会用 k mod 位数, 也就是如果k是32, 就相当于不移动, k是33, 就移动1位... 练习题很简单就不写了...

    2.2 整数表示

    2.2.1 整型数据类型

    C语言中支持多种整数数据类型来表述有限范围的整数(char, short, int, long, long long), 这些不同类型所分配的字节数根据机器的字长和编译器不用可能会不太一样, C语言标准只是给出了一个这些数据类型必须保证的取值范围, 而并不做明确要求.

     

    2.2.2 无符号数的编码

     

    2.2.3 补码编码

     

    实际上C语言标准并没有要求使用补发的形式来表示有符号正数, 但几乎所有的机器都是这么做的.  这里给出反码和原码的定义, 只做了解 :

    2.2.4 有符号数和无符号数之间转换

    总结下来我感觉有如下几点 :

    1. 对于相同字长的有符号数和无符号数而言, 互相转化, 他们的位模式(也就是每一位的值)是不变的, 变得只是解释方式...

    2. 对于同一个向量x, 如果我们计算B2U(x)-B2T(x), 会发现他们的0到w-2位的解释方式相同, 每一位的权相同, 互相抵消, 对于第w-1位, B2U(x)的权解释为2w-1而B2T(x)则正好相反解释为-2w-1,所以可以发现 B2U(x)-B2T(x) = 2* xw-1. 利用这个公式我们可以很轻松的得出结论 : T2U(x) = 2* xw-1 + x (x是补码值).

     

    2.25 C语言中的有符号数和无符号数

    C语言支持有符号数和无符号数, 虽然C语言标准未做规定, 但是大多数数字都默认是有符号的, 例如12345或者是0x1A2B这样的常理, 通常被认为是有符号的, 要创建无符号数通常要加上'u' 或者 'U' 的后缀.

    同时C语言对于有符号和无符号数的一些处理方式, 常常会导致一些奇怪的结果, 比如当同时将有符号数和无符号数进行运算时, 它默认转化有符号数为无符号数 : 那么在进行类似于 -1 < 0U 的比较时, 这个表达式的结果是0, 而按照正常逻辑应该是1.

    另外一个指的注意的问题是在C语言的头文件 limits.h 的头文件中有如下一句话 :

    #define INT_MIN (-INT_MAX -1) 为什么要这样麻烦的 -2147483647-1 而不是直接-2147483648呢? 原因就在于C语言编译器是识别到 2147483648 这个token的时候发现它的数值已经超过了int的范围, 已经默认将它识别为了long 或者 long long, 然后在进行取负操作的, 这样的话宏定义出来的值得类型不会是一个int, 所以不行.

     

    2.26 扩展一个数字的位的表示

    现在我们来考虑如何将较小的数字的位转换为一个更大的数据类型 (将较大的转化为较小的暂且不考虑), 对于无符号数而言, 只需要在扩展位上全部都补0就行了, 这种运算也称之为零扩展, 对于有符号数(补码数字)我们使用符号扩展, 也就是拓展位上全补上最高有效位的数字... 我们可以尝试着证明为什么这样做的结果是有效果的, 这里我们采用数学归纳法, 先证明对w位的补码数字, 扩展为w+1位时, 该补码数字值不变, 那么对于w+k, k为任意位时, 这个结论仍会成立...

    另外还有一点值得注意的地方 : 如果我们将一个一个short转化为一个unsigned时, 结果其实是不确定的, 因为你会发现如果short先转化为unsigned short再转为unsigned int的结果和先转化为int 在转化为unsigned int 得出的结果不同, 而C语言标准规定的规则应该属于后者... 所以 :

    1 #include <stdio.h>
    2 
    3 int main(void){
    4     short sx = -12345;
    5     unsigned uy = sx;
    6     printf("uy = %u\n", uy);  // 结果应该是这样 : uy = 4294954951 而不是 53191...
    7 return 0;
    8 }

     

    2.27 截断数字

    现在我们来考虑较大的数字转化为较小的数字(这里的大小指的是表示他们的数的位的大小而不是数字的实际大小), 例如对于w位的数字要截断为k位, 这时我们通常将w位数字的高w-k位舍去, 以这样的方式进行转换. 所以对于无符号数而言, 将它截断到k位就相当于是 x mod 2k, 当然对于有符号而言, 其实位值仍然是低k位的位值, 只是解释方式不同而已.

     

    2.28 关于有符号数与无符号数的建议

     

    所以碰到有符号数和无符号数隐式转换时要特别小心, 比如在练习题中 :

    对于length = 0, 如果第14行不将其转换为int的话, length-1的值作为无符号数在这里可以认为无限大, 这个for会无限循环...

     1 #include<stdio.h>
     2 
     3 float sum(float a[], unsigned length);
     4 
     5 int main(void){
     6   float a[] = {1.2, 1.3, 1.4};
     7   printf("%f\n", sum(a, 0));
     8   printf("%u\n", 0u - 1);
     9 }
    10 
    11 float sum(float a[], unsigned length){
    12   int i = 0;
    13   float re = 0;
    14   for(; i <= (int)(length - 1); ++i){
    15     re += a[i];
    16   }
    17 
    18   return re;
    19 }

     

    这里可能还是不太容易错, 书中的第二个例子非常好 :

    如果我们想要写一个函数来判断两个字符串的长短, 极有可能写出下面这个longer() 的这种形式, 不幸的是这是错的, 因为strlen()的返回值是size_t类型, 这个类型实际上在<stdio.h> 是被定义成了unsigned int类型的, 单看strlen() 确实应该被定义成unsigned int类型, 毕竟它代表的是一个长度, 但是两者一结合就错了, 所以特别要小心...

     1 #include<stdio.h>
     2 #include<string.h>
     3 
     4 int longer(char*s, char* t){
     5   return strlen(s) - strlen(t) > 0;
     6 }
     7 
     8 int main(void){
     9   printf("%d\n", longer("abc", "ab"));
    10   printf("%d\n", longer("a", "ab"));
    11   printf("%d\n", 1u - 2u);
    12   printf("%d\n", 1u - 2u > 1000);
    13   printf("%d\n", 1u > -1);
    14   printf("%d\n", 1u + 1 > 0);
    15 }

     

    转载于:https://www.cnblogs.com/nzhl/p/5607193.html

    展开全文
  • 题目38 题目信息 运行结果 本题排行 讨论区 布线问题 时间限制:1000 ms | 内存限制:65535 KB 难度:4 ...第一行是一个整数n表示有n组测试数据。...每组测试数据第一行是两个整数v,e. ...(哪两栋...

    布线问题

    时间限制:1000 ms  |  内存限制:65535 KB

    难度:4

    输入

    第一行是一个整数n表示有n组测试数据。(n<5)
    每组测试数据的第一行是两个整数v,e.
    v表示学校里楼的总个数(v<=500)
    随后的e行里,每行有三个整数a,b,c表示a与b之间如果建铺设线路花费为c(c<=100)。(哪两栋楼间如果没有指明花费,则表示这两栋楼直接连通需要费用太大或者不可能连通)
    随后的1行里,有v个整数,其中第i个数表示从第i号楼接线到外界供电设施所需要的费用。( 0<e<v*(v-1)/2 )
    (楼的编号从1开始),由于安全问题,只能选择一个楼连接到外界供电设备。
    数据保证至少存在一种方案满足要求。

    输出

    每组测试数据输出一个正整数,表示铺设满足校长要求的线路的最小花费。

    样例输入

    1
    4 6
    1 2 10
    2 3 10
    3 1 10
    1 4 1
    2 4 1
    3 4 1
    1 3 5 6

    样例输出

    4

    描述

    南阳理工学院要进行用电线路改造,现在校长要求设计师设计出一种布线方式,该布线方式需要满足以下条件:
    1、把所有的楼都供上电。
    2、所用电线花费最少

    此类是属于简单的最小生成树题,两种算法的去bilibili看懂原理基本就可以自己打代码了(不过的看了kruskal算法原理还是有点懵逼,不太会怎么打,一直在wa,runtim error,(QAQ)(太菜了~)

    prim算法代码

    #include<cstdio>
    #include<iostream>
    #include<cstring> 
    #include<algorithm>
    #include<string>
    #include<cmath>
    #include<stdlib.h>
    #include<queue>
    #include<vector>
    #include<assert.h>
    #include<map>
    #include<set>
    #include<stack>
    #define in(a) scanf("%d",&a)
    #define ind(a) scanf("%lld",&a)
    #define inc(a) scanf("%c",&a)
    #define mem(a) memset(a,0,sizeof(a))
    using namespace std;
    #define rep(i,a,n) for (int i=a;i<n;i++)
    #define per(i,a,n) for (int i=n-1;i>=a;i--)
    #define pb push_back
    #define mp make_pair
    #define all(x) (x).begin(),(x).end()
    #define fi first
    #define se second
    #define SZ(x) ((int)(x).size())
    typedef vector<int> VI;
    typedef long long ll;
    typedef pair<int,int> PII; 
    const ll mod=1000000007;
    ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); 
    for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
    ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
    const int maxn=550;
    const int inf=0x3f3f3f3f;
    int ma[maxn][maxn];
    int low[maxn];
    bool vis[maxn];
    int v;
    int prim()
    {
    	vis[1]=1;
    	for(int i=1;i<=v;i++) low[i]=ma[1][i];
    	int pos;
    	int ans=0;
    	for(int i=0;i<v-1;i++)
    	{
    		int minx=inf;
    		for(int j=1;j<=v;j++)
    		{
    			if(!vis[j]&&low[j]<minx) 
    			{
    				minx=low[j];
    				pos=j;
    			}
    		}
    		ans+=low[pos];
    		vis[pos]=1;
    		
    		for(int j=1;j<=v;j++)
    		{
    			if(!vis[j]&&low[j]>ma[pos][j]) low[j]=ma[pos][j];
    		}
    	}
    	return ans;
    }
    int main()
    {
    	int t;
    	in(t);
    	while(t--)
    	{
    		int e;
    		in(v);in(e);
    		memset(ma,inf,sizeof(ma));
    		rep(i,0,e)
    		{
    			int a,b,c;
    			scanf("%d%d%d",&a,&b,&c);
    			ma[a][b]=ma[b][a]=c;
    		}
    		mem(vis);
    		mem(low);
    		int minx=inf;
    		int x;
    		rep(i,0,v)
    		{
    			in(x);
    			if(x<minx) minx=x;
    		}
    		printf("%d\n",prim()+minx);
    	}
    	
     } 

    kruskal算法代码:

     
    #include<cstdio>
    #include<iostream>
    #include<cstring> 
    #include<algorithm>
    #include<string>
    #include<cmath>
    #include<stdlib.h>
    #include<queue>
    #include<vector>
    #include<assert.h>
    #include<map>
    #include<set>
    #include<stack>
    #define in(a) scanf("%d",&a)
    #define ind(a) scanf("%lld",&a)
    #define inc(a) scanf("%c",&a)
    #define mem(a) memset(a,0,sizeof(a))
    using namespace std;
    #define rep(i,a,n) for (int i=a;i<n;i++)
    #define per(i,a,n) for (int i=n-1;i>=a;i--)
    #define pb push_back
    #define mp make_pair
    #define all(x) (x).begin(),(x).end()
    #define fi first
    #define se second
    #define SZ(x) ((int)(x).size())
    typedef vector<int> VI;
    typedef long long ll;
    typedef pair<int,int> PII; 
    const ll mod=1000000007;
    ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); 
    for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
    ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
    const int maxn=550;
    const int inf=0x3f3f3f3f;
    struct node
    {
    	int x,y;
    	int cost;
    };
    //node a[maxn];
    int fa[maxn];
    int kruskal(node *a,int v)
    {
    	int i,j,s;
    	i=j=s=0;;
    	while(j<v-1)
    	{
    		int x=fa[a[i].x-1];
    		int y=fa[a[i].y-1];
    		if(x!=y)
    		{
    			for(int k=0;k<v;k++)
    				if(fa[k]==y)
    					fa[k]=x;
    			s+=a[i].cost;
    			j++;
    		}
    		i++;
    	}
    	return s;
    }
    bool cmp(const node &a,const node &b)
    {
    	return a.cost<b.cost;
    }
    int main()
    {
    	int t;
    	in(t);
    	int v,e;
    	while(t--)
    	{
    		in(v);in(e);
    		node a[e];
    		rep(i,0,e)
    		{
    			in(a[i].x);
    			in(a[i].y);
    			in(a[i].cost);
    		}
    		sort(a,a+e,cmp);
    		
    		int minx=inf;
    		int x;
    		rep(i,0,v)
    		{
    			in(x);
    			if(x<minx) minx=x;
    			fa[i]=i;
    		}
    		printf("%d\n",kruskal(a,v)+minx);
    	}
    }        

     

    展开全文
  • 假设检验的两类错误及功效

    千次阅读 2018-07-17 17:26:43
    由于假设检验是根据有限样本信息对总体作推断,不论做出哪种推断结论(拒绝原假设H0和不拒绝原假设H0),都由可能因为抽样等原因发生错误。 二、假设检验的两类错误 1. 第I类错误 实际情况和H0一致,仅由于抽样...
  • 简历信息有一块内容是校内活动,包含校内荣誉、校内职务等内容 我有两种方案,但是不知道种方案比较好,请各位大神帮我看看 ...这是我能想到的两种方法,请帮我看看种好,或者没有更优法子
  • Stateful Session Bean 与 Stateless Session Bean ,这两种的 Session Bean都可以将系统逻辑放在 method之中执行,不同是 Stateful Session Bean 可以记录呼叫者状态,因此通常来说,一个使用者会一个相对应...
  • 【题目描述】 动物王国中三类动物A,B,C,这...人用两种说法对这N个动物所构成食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类。 第二种说法是"2 X Y",表示X吃Y。 此人对N个动物,用上述两种说...
  • 【题目描述】 动物王国中三类动物A...人用两种说法对这N个动物所构成食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类。 第二种说法是"2 X Y",表示X吃Y。 此人对N个动物,用上述两种说法,一句...
  • 若不知道要导入,可以在播放时抛出异常崩溃中根据异常信息提示导入。 初始化 下面是最简单初始化以及播放音频代码,更多功能请阅读使用文档或者查看项目demo。 open class TestApplication : Application...
  • 关于Buddy(伙伴)算法讨论

    千次阅读 2009-03-28 12:20:00
    对伙伴系统种的位图作用没有搞...当位图中一位为0,表示块都空或都闲当位图中一位为1,表示有一块为忙位大侠能详细谈谈位图动作?到底是怎么异或? 位图某位对应于个伙伴块,为1就表示其中一块忙
  • 把allow_url_fopen给启用,改成 allow_url_fopen = On 这样做可以解决某些人问题,人说在php.ini中,这样个选项:allow_url_fopen =on(表示可以通过url打开远程文件),user_agent=”PHP”(表示通过哪种脚本...
  • 本文针对卡随机化问题进行了全面实验分析,目的是确定1)两种理论方法中的哪一种预测更准确; 2)不同统计检验是否产生不同随机洗牌阈值数; 3)是否手动或机械混洗可以更有效地将甲板随机分配给定数量混洗...
  • 在WWW上,每一个信息资源都一个唯一的与之对应的地址,这个地址就叫做URL(Uniform Resource Locator,统一资源定位符),是对可以从互联网上得到的资源的位置和访问方法的一简洁的表示,它包含的信息指出文件的...
  • ʕ•̫͡•ʔ❤ʕ•̫͡•ʔ题目要求ʕ•̫͡•ʔ❤ʕ•̫...根据这些信息,下面一项哨声可以表示:SCRATCH? 先不要下滑看答案,自己想想选哪个呢? | 下 | 滑 | 查 | 看 | 参 | 考 ...
  • 字符编码前世今生

    2019-10-06 18:01:29
    我们知道,由于计算机只能识别0和1(冯·洛伊曼体系结构),因而所有的信息最终都需要表示为一个二进制字符串,字符串每一个二进制位(bit)0和1两种状态。比如,当我们需要把字符'A'存入计算机时,应该对应...
  • 的文献还使用如OC-3C的表示方法,这区别吗? 问题2-10:ATM是异步传递方式。是否ATM方式与同步通信完全无关? 第3章 数据链路层 问题3-1:在1999年4月出版的《计算机网络》(第2版)的1.3.2节中这样的话: ...
  • 视频讲解 概述 纠错编码:在接收端不但能检查错误,而且还能纠正检查出来错误。常见纠错编码是海明编码 海明码:在信息字段中插入若干位数据,...又因为每一位数据0、1个状态,所以r位可以表示2^r...
  • 1、用两种方式根据部门号从高到低,工资从低到高列出每个员工的信息。 91 2、列出各个部门中工资高于本部门平均工资员工数和部门号,并按部门号排序 91 3、存储过程与触发器必须讲,经常被面试到? 92 4、数据库...
  • 原创 小明和小刚一同坐飞机去旅游,他们现在位于1号城市,目标是5号城市,可是1号城市并没有到5号城市... 接下来e行,每行输出两个整数,分别代表哪两个城市直航; 输出  最少转机次数 BFS——一旦找...
  • 子网掩码表示所使用网络属于哪种网络段,个IP地址同属于一个网段就可以直接通信,当属于不同网络段时则需要网关来发挥作用了;而网关指是所发送的信息(数据包)出去出口,一般指是路由器地址。 什么是...
  • PE知识复习之PE节表

    2018-09-29 20:26:00
    一丶节表信息,PE两种状态.以及重要两个成员解析.  确定节表位置: DOS + NT头下面就是节表.  确定节表数量: 节表数量在文件头中存放着.可以准确知道节表多少个.  节表是一个结构体数组.没一个节表表示了数据...
  • 3.头元素包含文档相关信息,其中一些子元素,用于表示页面标题(title),到其他web资源链接(link),样式信息(style),脚本(script),一般信息(meta)及其他。强烈建议提供一个,meta元素,
  • 5.17 说真的,真机器用非零空指针吗,或者不同类型用不同的表示? 地址0上到底什么? 5.18 运行时的整数值0转换为指针以后一定是空指针吗? 5.19 如何访问位于机器地址0处的中断向量?如果我将指针值设为0,...
  • 弄系统应该经常碰到子节点、父节点之类词汇,无论都是某个表里面一条记录,所不同是:子节点记录了父节点编号信息,父节点只需要记录其下多少个子节点即可。 父节点对于其下子节点记录,可以...
  • 5.17 说真的,真机器用非零空指针吗,或者不同类型用不同的表示?  地址0上到底什么?  5.18 运行时的整数值0转换为指针以后一定是空指针吗? 5.19 如何访问位于机器地址0处的中断向量?如果我将指针值设为...
  • 本书以问答的形式组织内容,讨论了学习或使用C语言的过程中经常... 5.17 说真的,真机器用非零空指针吗,或者不同类型用不同的表示? 90 地址0 上到底什么? 90 5.18 运行时的整数值0转换为指针以后一定是空指针...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 176
精华内容 70
关键字:

信息的表示有哪两种