精华内容
下载资源
问答
  • 在复习《计算机组成原理》时,遇到了有符号数与无符号数之间转换的问题,为了应对这类问题,楼主仔细查阅资料再结合做题总结出一些心得,内容如下: 注意: 1、字长都用的是 16 (方便些) 2、建议先去大致了解...

    楼主有话要说:

    在复习《计算机组成原理》时,遇到了有符号数与无符号数之间转换的问题,为了应对这类问题,楼主仔细查阅资料再结合做题总结出一些心得,内容如下(如果有新的总结,会反复修改):

    注意:

    1、字长都用的是 16 位(方便些)

    2、建议先去大致了解下 C++ 里基本数据类型的字节长度和示数范围;如:

    char1 byteint

    4 byte 

    short [int]2 bytefloat4 bytelong [int]4 byte
    signed char1 bytesigned int4 bytesigned short [int]2 bytedouble8 bytesigned long [int]4 byte
    unsigned char1 byteunsigned int4 byteunsigned short [int]2 bytelong double8 byteunsigned long [int]4 byte

    3、(1)定点整数的范围( 16 bit ) :有符号:-32767 <= x <= 32767

    (2)定点整数补码的范围( 16 bit ) :有符号:-32768 <= x <= 32767

    4、在计算机中,负数一般用补码表示。注意:本文所有例子,都是先将要赋值的数化为补码的形式再进行转换。

    5、理清 0 和 1 的原码、反码、补码。(0 的补码和移码是只有一种形式;正数的原码、反码、补码都相同;)

    原码反码补码
    [ +0 ]0000 00000000 00000000 0000
    [ -0 ]1000 00001111 11110000 0000
    [ +1 ]0000 00010000 00010000 0001
    [ -1 ]1000 00011111 11101111 1111

    一、同类型(如同为有符号数,或同为无符号数)转换

    (一)1. 同为无符号数(由短变长:在最高位加 “ 0 ”。)

    unsigned short x = 255;  //short为2字节
    
    unsigned int y = x;  //int为4字节

    x = 255 D = 1111 1111 B

    y = 0000 0000 1111 1111 B = 255 D

    总结:同为无符号数时,由较短的数变成较长的数,即在最高位加 “ 0 ”,称为 “ 零扩展 ”。

    (一)2. 同为无符号数(由长变短:在最高位加 “ 0 ”。)

    unsigned int x = 255;  //short为2字节
    
    unsigned short y = x;  //int为4字节

    x = 255 D = 0000 0000 1111 1111 B

    y = 1111 1111 B = 255 D

    总结:同为无符号数时,由较长的数变成较短的数,即去掉高位的 “ 0 ” 字节,低位的字节不变。

    (二)同为有符号数(由短变长和由长变短的情况同 “(一)同为无符号数 ” 一样)

    short x = -120;  //short为2字节
    
    int y = x;  //int为4字节

    x = -120 D ,其原码为:1111 1000 B,其补码为:1000 1000 B (= 88 H)

    y = 1111 1111 1000 1000 B = -120 D (= FF 88 H)

    总结:同为有符号数时,使用符号扩展,即为负数时,高位的字节加 “ 1 ”;为正数时,高位的字节加 “ 0 ”。

    二、有符号数与无符号数之间的转换

    (一)有符号数转为无符号数

    short n = -1;
    
    unsigned short m = n;

    n = -1 D,其补码为:1111 1111 B 

    m = 1111 1111 B = 65535 D

    注释:n 的最高位为 “ 1 ” 表示的是符号位,因为 m 为无符号数,所以 m 的最高位为 “ 1 ” 表示的是“ 2的7次方 ”。

    总结:有符号数转为无符号数时,当有符号数为负数时,关键是将最高位的 “ 1 ” 变成 “ 2的某次方 ”。

    (二)无符号数转为有符号数

    unsigned short a = 65535;
    
    short b = -1;

    a = 65535 = FF FF FF FF H

    b 的补码即为:FF FF FF FF H = -1 D

    注释:因为 b 为有符号数,最高位可知为 “ 1 ”,所以 b 为负数,可知其值为 -1。

    总结:无符号数转为有符号数时,先得出赋值数的补码,即为被赋值数的补码;再由被赋值数的补码取反加一得到原码,再计算即得十进制的数值。

    再举个例子:

    unsigned char i = 130;
    
    char k = i;

    i = 130 D = 1000 0010 B (注意:正数的原码 = 正数的补码 = 正数的反码)

    k 的补码为:1000 0010 B,进行取反加一后得原码为:1111 1110 B,因为 k 为有符号数,最高位又为 “ 1 ”,所以 k 为负数,即为 -126 D。

    练习:(附上2011年统考真题,便于理解巩固)

    假定在一个8位字长的计算机中运行如下C程序段:

    unsigned int x = 134;
    unsigned int y = 246;
    int m = x;
    int n = y;
    unsigned int z1 = x - y;
    unsigned int z2 = x + y;
    int k1 = m - n;
    int k2 = m + n;
    

    若编译器编译时将 8 个 8 位寄存器 R1 - R8 分别分配给变量x、y、m、n、z1、z2、k1、k2,请回答下列问题(提示:带符号整数用补码表示)

    ( 1 )执行上述程序段后,寄存器 R1、 R5 和 R6 的内容分别是什么?(用十六进制表示)

    ( 2 )执行上述程序段后,变量 m 和 k1 的值分别是多少?(用十进制表示)

    ( 3 )上述程序段涉及带符号整数加/减、无符号整数加/减运算,这四种运算能否利用同一个加法器辅助电路实现?简述理由。

    ( 4 )计算机内部如何判断带符号整数加/减运算的结果是否发生溢出?上述程序段中,哪些带符号整数运算语句的执行结果会发生溢出?

    解:( 1 )寄存器 R1、 R5 和 R6 的内容,分别对应 x, z1(x - y) , z2(x + y)。

    x = 134 D,其原码等于补码为 1000 0110 B,即为 86 H,即为 R1

    y = 246 D,其原码等于补码为 1111 0110 B,即为 F6 H

    z1 = x - y = x 的补码 + [-y] 的补码 = 1000 0110 B + 0000 1010 B = 1001 0000 B = 90 H,即为 R5

    z2 = x + y = x 的补码 + y 的补码 = 1000 0110 B + 1111 0110 B = (1) 0111 1100 B = 7C H,即为 R6

    (注意:z2 处有溢出,但无符号整数的加减运算,一般不考虑溢出情况,只是输出的时候若是有符号数的最高位是符号位,意思是 z2 若转换为有符号数,最高位为 1。)

    所以 R1 = 134 = 86 H;
            R5 = 90 H;
            R6 = 7C H;

    ( 2 )m 为无符号数整型 x 转为有符号数整型,n 为无符号数整型 y 转为有符号数整型,由(1)知

    x 的补码为 1000 0110 B,y 的补码为 1111 0110 B,所以

    m 的补码为 1000 0110 B,其原码为1111 1010 B,其值为 -122 D

    n 的补码为 1111 0110 B,其原码为 1000 1010 B,其值为 -10 D

    即 k1 = m - n = m 的补码 + -n 的补码 = 1000 0110 B + 0000 1010 B = 1001 0000 B = 90 H,求得其原码为 1111 0000 B = -112 D

    顺带求下 k2 = m + n = m 的补码 + n 的补码 = 1000 0110 B + 1111 0110 B = (1) 0111 1100 B = 7C H(注意:此处有溢出)

    所以,m = -122;
               k1 = -112;

    题外话(对 OF 、SF、CF 也要注意区分):

    k2 = m + n,由已知 m = -122,n = -10,可知两者相加仍为负数,但结果为正。所以,溢出标志位 OF = 1, 表示溢出,说明寄存器 R6 中的内容不是真正的结果;符号标志位 SF = 0,表示结果为正数(溢出标志为1,说明符号标志有错),进位标志位 CF = 1,仅表示加法器最高有进位,对运算结果不说明什么。

    ( 3 ) 能。n 位加法器实现的是模 2 的 n 次方无符号整数加法运算。因为在计算机中,正数和负数均用补码来表示,带符号整数的加法运算和无符号整数的加法运算,均可直接用加法器实现。对于减法运算,只要减数的补码加上被减数的负数的补码即可实现,但要考虑溢出情况。所以带符号整数加/减、无符号整数加/减运算均可用同一个加法器辅助电路实现(溢出判断电路不同)。

    ( 4 )是。计算机内部判断带符号整数加/减运算的结果是否发生溢出,有 3 种方法。一是若加法器的两个输入端(加法)的符号相同,且不同于输出端(和)的符号,则结果溢出。二是加法器完成加法操作时,若次高位(最高数位)的进位与最高位(符号位)的进位不同,则结果溢出。三是两个带符号整数均为负数,两者相加后,结果小于 8 位二进制所能表示的最小负数,则结果溢出。

    在执行关于 k2 的语句时会发生溢出。k2 = 1000 0110 B + 1111 0110 B = (1) 0111 1100 B,括号中为加法器的进位,因为 2 个带符号整数均为负数,经过加法运算后得出结果的最高位为 0 ,所以溢出。

    (溢出判断方法简单版:双符号位判决法、最高位进位、符号相同操作数的运算后与原操作数的符号不同,则结果溢出。)

    注释:

    双符号位判决法:

    用补码进行双符号位运算(正数符为 00, 负数符号为 11),第一符号位表示最终结果的符号,第二符号位表示运算结果是否溢出。第一符号位和第二符号位相同,则未溢出,;若不同,则溢出。具体如下:

    若运算结果的符号位为 01, 则为正溢出;

    若结果双符号为 10, 则为负溢出;

    若结果的双符号位为 00,结果为正数,无溢出。

    若结果的双符号位为 11,结果为负数,无溢出。

    展开全文
  • typedef intBOOL;#define TRUE 1;...#define UINT_MAX 0xffffffff /* maximum unsigned int value */enumScale24AsciiVal{sav_aADis= 32, //小写字母与大写字母ASCII码差值sav_chIntDis = 48, //字符‘0’AS...

    typedef intBOOL;#define TRUE 1;

    #define FALSE 0;

    #define UINT_MAX 0xffffffff /* maximum unsigned int value */

    enumScale24AsciiVal

    {

    sav_aADis= 32, //小写字母与大写字母ASCII码差值

    sav_chIntDis = 48, //字符‘0’ASCII码值

    };static const char scale24[24] = {‘0‘, ‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘, ‘A‘, ‘B‘,‘C‘, ‘F‘, ‘H‘, ‘K‘, ‘M‘, ‘P‘, ‘S‘, ‘T‘, ‘U‘, ‘W‘, ‘X‘, ‘Y‘};//判断是否为合法的二十四进制编码字符

    BOOL IsScale24(const char ch, unsigned int*nVal);/*二十四进制编码串转换为32位无符号整数, 其中:

    参数:

    str 二十四进制编码串

    length 二十四进制编码串长度, 若 < 0 则为 str 以 ‘\0‘ 结尾

    code 转换返回码, 若 code == NULL 则忽略返回码

    返回值:

    (值) 转换后的返回值, 转换是否成功从 code 得到。*/unsignedint C24ToU32(const char* str, int length, int*code)

    {

    unsignedint result = 0;const char* pStr =str;

    unsignedint nVal = 0; //位值

    int codeIdx = 1; //非法字符在编码串中的序号

    if (code != NULL) *code = 0;if( (pStr==NULL) || ((pStr=="") && (length==0)) )

    {if (code !=NULL)*code = -1; //转换失败, 可能参数错误或字符串为空串

    }else{if(length < 0) //str 以 ‘\0‘ 结尾

    {while(*pStr != ‘\0‘)

    {if(IsScale24(*pStr, &nVal))

    {if ( ((UINT_MAX-nVal)/24) < result ) //转换失败(溢出)

    {if (code !=NULL)*code =codeIdx;break;

    }elseresult= result*24 + nVal; //进位并加位值

    }else{if (code !=NULL)*code = codeIdx; //转换失败, 第 code 个字符(包含第一个字符)为非二十四进制编码

    break;

    }

    codeIdx++;

    pStr++;

    }

    }else{while(codeIdx <=length)

    {if(IsScale24(*pStr, &nVal))

    {if ( ((UINT_MAX-nVal)/24) < result ) //转换失败(溢出)

    {if (code !=NULL)*code =codeIdx;break;

    }elseresult= result*24 + nVal; //进位并加位值

    }else{if (code !=NULL)*code = codeIdx; //转换失败, 第 code 个字符(包含第一个字符)为非二十四进制编码

    break;

    }

    codeIdx++;

    pStr++;

    }

    }

    }returnresult;

    }/*判断是否为合法的二十四进制编码字符, 其中:

    参数:

    ch 待判定字符

    nVal ch若合法,则nVal为ch所对应的二十四进制字符位值(‘A‘->10,‘B‘->11,‘C‘->12...)

    返回值:

    (值) ch合法->true,非法->false。*/BOOL IsScale24(const char ch, unsigned int*nVal)

    {

    BOOL result=FALSE;

    unsignedint nbegin = 10; //二分查找ch,初始起始位置

    unsigned int nEnd = 23; //二分查找ch,初始结束位置

    unsigned int nMid = 16; //二分查找ch,初始折半位置

    unsigned int nOffset = 0;char chScale= 0;if((ch >= ‘0‘) && (ch <=‘9‘)) //‘0‘...‘9‘

    {*nVal = (unsigned int)(ch-sav_chIntDis);

    result=TRUE;

    }else if (ch >= ‘A‘ && ch <= ‘y‘)

    {if (ch > ‘Z‘) //ch为小写字母

    nOffset =sav_aADis;//‘A(a)‘...‘Y(y)‘ 二分查找ch

    while ( nbegin <=nEnd ){

    chScale= scale24[nMid] +nOffset;if ( chScale ==ch )

    {*nVal =nMid;

    result=TRUE;break;

    }else if ( chScale >ch )

    nEnd= nMid - 1;elsenbegin= nMid + 1;

    nMid= (nbegin + nEnd) / 2;

    }

    }returnresult;

    }

    展开全文
  • typedef intBOOL;#define TRUE 1;...#define UINT_MAX 0xffffffff /* maximum unsigned int value */enumScale24AsciiVal{sav_aADis= 32, //小写字母与大写字母ASCII码差值sav_chIntDis = 48, //字符‘0’AS...

    typedef intBOOL;#define TRUE 1;

    #define FALSE 0;

    #define UINT_MAX 0xffffffff /* maximum unsigned int value */

    enumScale24AsciiVal

    {

    sav_aADis= 32, //小写字母与大写字母ASCII码差值

    sav_chIntDis = 48, //字符‘0’ASCII码值

    };static const char scale24[24] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B','C', 'F', 'H', 'K', 'M', 'P', 'S', 'T', 'U', 'W', 'X', 'Y'};//判断是否为合法的二十四进制编码字符

    BOOL IsScale24(const char ch, unsigned int*nVal);/*二十四进制编码串转换为32位无符号整数, 其中:

    参数:

    str 二十四进制编码串

    length 二十四进制编码串长度, 若 < 0 则为 str 以 '\0' 结尾

    code 转换返回码, 若 code == NULL 则忽略返回码

    返回值:

    (值) 转换后的返回值, 转换是否成功从 code 得到。*/unsignedint C24ToU32(const char* str, int length, int*code)

    {

    unsignedint result = 0;const char* pStr =str;

    unsignedint nVal = 0; //位值

    int codeIdx = 1; //非法字符在编码串中的序号

    if (code != NULL) *code = 0;if( (pStr==NULL) || ((pStr=="") && (length==0)) )

    {if (code !=NULL)*code = -1; //转换失败, 可能参数错误或字符串为空串

    }else{if(length < 0) //str 以 '\0' 结尾

    {while(*pStr != '\0')

    {if(IsScale24(*pStr, &nVal))

    {if ( ((UINT_MAX-nVal)/24) < result ) //转换失败(溢出)

    {if (code !=NULL)*code =codeIdx;break;

    }elseresult= result*24 + nVal; //进位并加位值

    }else{if (code !=NULL)*code = codeIdx; //转换失败, 第 code 个字符(包含第一个字符)为非二十四进制编码

    break;

    }

    codeIdx++;

    pStr++;

    }

    }else{while(codeIdx <=length)

    {if(IsScale24(*pStr, &nVal))

    {if ( ((UINT_MAX-nVal)/24) < result ) //转换失败(溢出)

    {if (code !=NULL)*code =codeIdx;break;

    }elseresult= result*24 + nVal; //进位并加位值

    }else{if (code !=NULL)*code = codeIdx; //转换失败, 第 code 个字符(包含第一个字符)为非二十四进制编码

    break;

    }

    codeIdx++;

    pStr++;

    }

    }

    }returnresult;

    }/*判断是否为合法的二十四进制编码字符, 其中:

    参数:

    ch 待判定字符

    nVal ch若合法,则nVal为ch所对应的二十四进制字符位值('A'->10,'B'->11,'C'->12...)

    返回值:

    (值) ch合法->true,非法->false。*/BOOL IsScale24(const char ch, unsigned int*nVal)

    {

    BOOL result=FALSE;

    unsignedint nbegin = 10; //二分查找ch,初始起始位置

    unsigned int nEnd = 23; //二分查找ch,初始结束位置

    unsigned int nMid = 16; //二分查找ch,初始折半位置

    unsigned int nOffset = 0;char chScale= 0;if((ch >= '0') && (ch <='9')) //'0'...'9'

    {*nVal = (unsigned int)(ch-sav_chIntDis);

    result=TRUE;

    }else if (ch >= 'A' && ch <= 'y')

    {if (ch > 'Z') //ch为小写字母

    nOffset =sav_aADis;//'A(a)'...'Y(y)' 二分查找ch

    while ( nbegin <=nEnd ){

    chScale= scale24[nMid] +nOffset;if ( chScale ==ch )

    {*nVal =nMid;

    result=TRUE;break;

    }else if ( chScale >ch )

    nEnd= nMid - 1;elsenbegin= nMid + 1;

    nMid= (nbegin + nEnd) / 2;

    }

    }returnresult;

    }

    展开全文
  • 理解有符号数和无符号数负数在计算机中如何表示呢?这一点,你可能听过两种不同的回答。一种是教科书,它会告诉你:计算机用“补码”表示负数。可是有关“补码”的概念一说就得一节课,这一些我们需要在第6章中用一...

    理解有符号数和无符号数负数在计算机中如何表示呢?

    这一点,你可能听过两种不同的回答。

    一种是教科书,它会告诉你:计算机用“补码”表示负数。可是有关“补码”的概念一说就得一节课,这一些我们需要在第6章中用一章的篇幅讲2进制的一切。再者,用“补码”表示负数,其实一种公式,公式的作用在于告诉你,想得问题的答案,应该如何计算。却并没有告诉你为什么用这个公式就可以和答案?

    另一种是一些程序员告诉你的:用二进制数的最高位表示符号,最高位是0,表示正数,最高位是1,表示负数。这种说法本身没错,可是如果没有下文,那么它就是错的。至少它不能解释,为什么字符类型的-1用二进制表示是“1111 1111”(16进制为FF);而不是我们更能理解的“1000 0001”。(为什么说后者更好理解呢?因为既然说最高位是1时表示负数,那1000 0001不是正好是-1吗?)。

    让我们从头说起。

    1、你自已决定是否需要有正负。

    就像我们必须决定某个量使用整数还是实数,使用多大的范围数一样,我们必须自已决定某个量是否需要正负。如果这个量不会有负值,那么我们可以定它为带正负的类型。

    在计算机中,可以区分正负的类型,称为有符类型,无正负的类型(只有正值),称为无符类型。

    数值类型分为整型或实型,其中整型又分为无符类型或有符类型,而实型则只有符类型。

    字符类型也分为有符和无符类型。

    比如有两个量,年龄和库存,我们可以定前者为无符的字符类型,后者定为有符的整数类型。

    2、使用二制数中的最高位表示正负。

    首先得知道最高位是哪一位?1个字节的类型,如字符类型,最高位是第7位,2个字节的数,最高位是第15位,4个字节的数,最高位是第31位。不同长度的数值类型,其最高位也就不同,但总是最左边的那位(如下示意)。字符类型固定是1个字节,所以最高位总是第7位。

    (红色为最高位)

    单字节数: 1111 1111

    双字节数: 1111 1111 1111 1111

    四字节数: 1111 1111 1111 1111 1111 1111 1111 1111

    当我们指定一个数量是无符号类型时,那么其最高位的1或0,和其它位一样,用来表示该数的大小。

    当我们指定一个数量是无符号类型时,此时,最高数称为“符号位”。为1时,表示该数为负值,为0时表示为正值。

    3、无符号数和有符号数的范围区别。

    无符号数中,所有的位都用于直接表示该值的大小。有符号数中最高位用于表示正负,所以,当为正值时,该数的最大值就会变小。我们举一个字节的数值对比:

    无符号数: 1111 1111    值:255 1* 27 + 1* 26 + 1* 25 + 1* 24 + 1* 23 + 1* 22 + 1* 21 + 1* 20

    有符号数: 0111 1111    值:127          1* 26 + 1* 25 + 1* 24 + 1* 23 + 1* 22 + 1* 21 + 1* 20

    同样是一个字节,无符号数的最大值是255,而有符号数的最大值是127。原因是有符号数中的最高位被挪去表示符号了。并且,我们知道,最高位的权值也是最高的(对于1字节数来说是2的7次方=128),所以仅仅少于一位,最大值一下子减半。

    不过,有符号数的长处是它可以表示负数。因此,虽然它的在最大值缩水了,却在负值的方向出现了伸展。我们仍一个字节的数值对比:

    无符号数:                        0 ----------------- 255

    有符号数:         -128 --------- 0 ---------- 127

    同样是一个字节,无符号的最小值是 0 ,而有符号数的最小值是-128。所以二者能表达的不同的数值的个数都一样是256个。只不过前者表达的是0到255这256个数,后者表达的是-128到+127这256个数。

    一个有符号的数据类型的最小值是如何计算出来的呢?

    有符号的数据类型的最大值的计算方法完全和无符号一样,只不过它少了一个最高位(见第3点)。但在负值范围内,数值的计算方法不能直接使用1* 26 + 1* 25 的公式进行转换。在计算机中,负数除为最高位为1以外,还采用补码形式进行表达。所以在计算其值前,需要对补码进行还原。这些内容我们将在第六章中的二进制知识中统一学习。

    这里,先直观地看一眼补码的形式:

    以我们原有的数学经验,在10进制中:1 表示正1,而加上负号:-1 表示和1相对的负值。

    那么,我们会很容易认为在2进制中(1个字节): 0000 0001 表示正1,则高位为1后:1000 0001应该表示-1。

    然而,事实上计算机中的规定有些相反,请看下表:

    二进制值(1字节) 十进制值

    1000 0000 -128

    1000 0001 -127

    1000 0010 -126

    1000 0011 -125

    ... ...

    1111 1110 -2

    1111 1111 -1

    首先我们看到,从-1到-128,其二进制的最高位都是1(表中标为红色),正如我们前面的学。

    然后我们有些奇怪地发现,1000 0000 并没有拿来表示 -0;而1000 0001也不是拿来直观地表示-1。事实上,-1 用1111 1111来表示。

    怎么理解这个问题呢?先得问一句是-1大还是-128大?

    当然是 -1 大。-1是最大的负整数。以此对应,计算机中无论是字符类型,或者是整数类型,也无论这个整数是几个字节。它都用全1来表示 -1。比如一个字节的数值中:1111 1111表示-1,那么,1111 1111 - 1 是什么呢?和现实中的计算结果完全一致。1111 1111 - 1 = 1111 1110,而1111 1110就是-2。这样一直减下去,当减到只剩最高位用于表示符号的1以外,其它低位全为0时,就是最小的负值了,在一字节中,最小的负值是1000 0000,也就是-128。

    我们以-1为例,来看看不同字节数的整数中,如何表达-1这个数:

    字节数 二进制值 十进制值

    单字节数 1111 1111 -1

    双字节数 1111 1111 1111 1111 -1

    四字节数 1111 1111 1111 1111 1111 1111 1111 1111 -1

    可能有同学这时会混了:为什么 1111 1111 有时表示255,有时又表示-1?所以我再强调一下本节前面所说的第2点:你自已决定一个数是有符号还是无符号的。写程序时,指定一个量是有符号的,那么当这个量的二进制各位上都是1时,它表示的数就是-1;相反,如果事选声明这个量是无符号的,此时它表示的就是该量允许的最大值,对于一个字节的数来说,最大值就是255。

    原码、反码、补码

    我们已经知道计算机中,所有数据最终都是使用二进制数表达。

    我们也已经学会如何将一个10进制数如何转换为二进制数。

    不过,我们仍然没有学习一个负数如何用二进制表达。

    比如,假设有一 int 类型的数,值为5,那么,我们知道它在计算机中表示为:

    00000000 00000000 00000000 00000101

    5转换成二制是101,不过int类型的数占用4字节(32位),所以前面填了一堆0。

    现在想知道,-5在计算机中如何表示?

    在计算机中,负数以其正值的补码形式表达。

    什么叫补码呢?这得从原码,反码说起。

    原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。

    比如 00000000 00000000 00000000 00000101 是 5的 原码。

    反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。

    取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)

    比如:将00000000 00000000 00000000 00000101每一位取反,得11111111 11111111 11111111 11111010。

    称:11111111 11111111 11111111 11111010 是 00000000 00000000 00000000 00000101 的反码。

    反码是相互的,所以也可称:

    11111111 11111111 11111111 11111010 和 00000000 00000000 00000000 00000101 互为反码。

    补码:反码加1称为补码。

    也就是说,要得到一个数的补码,先得到反码,然后将反码加上1,所得数称为补码。

    比如:00000000 00000000 00000000 00000101 的反码是:11111111 11111111 11111111 11111010。

    那么,补码为:

    11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011

    所以,-5 在计算机中表达为:11111111 11111111 11111111 11111011。转换为十六进制:0xFFFFFFFB。

    再举一例,我们来看整数-1在计算机中如何表示。

    假设这也是一个int类型,那么:

    1、先取1的原码:00000000 00000000 00000000 00000001

    2、得反码:      11111111 11111111 11111111 11111110

    3、得补码:      11111111 11111111 11111111 11111111

    可见,-1在计算机里用二进制表达就是全1。16进制为:0xFFFFFF。

    码、反码、补码

    结束了各种进制的转换,我们来谈谈另一个话题:原码、反码、补码。

    我们已经知道计算机中,所有数据最终都是使用二进制数表达。

    我们也已经学会如何将一个10进制数如何转换为二进制数。

    不过,我们仍然没有学习一个负数如何用二进制表达。

    比如,假设有一 int 类型的数,值为5,那么,我们知道它在计算机中表示为:

    00000000 00000000 00000000 00000101

    5转换成二制是101,不过int类型的数占用4字节(32位),所以前面填了一堆0。

    现在想知道,-5在计算机中如何表示?

    在计算机中,负数以其正值的补码形式表达。

    什么叫补码呢?这得从原码,反码说起。

    原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。

    比如 00000000 00000000 00000000 00000101 是 5的 原码。

    反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。

    取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)

    比如:将00000000 00000000 00000000 00000101每一位取反,得11111111 11111111 11111111 11111010。

    称:11111111 11111111 11111111 11111010 是 00000000 00000000 00000000 00000101 的反码。

    反码是相互的,所以也可称:

    11111111 11111111 11111111 11111010 和 00000000 00000000 00000000 00000101 互为反码。

    补码:反码加1称为补码。

    也就是说,要得到一个数的补码,先得到反码,然后将反码加上1,所得数称为补码。

    比如:00000000 00000000 00000000 00000101 的反码是:11111111 11111111 11111111 11111010。

    那么,补码为:

    11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011

    所以,-5 在计算机中表达为:11111111 11111111 11111111 11111011。转换为十六进制:0xFFFFFFFB。

    再举一例,我们来看整数-1在计算机中如何表示。

    假设这也是一个int类型,那么:

    1、先取1的原码:00000000 00000000 00000000 00000001

    2、得反码:      11111111 11111111 11111111 11111110

    3、得补码:      11111111 11111111 11111111 11111111

    可见,-1在计算机里用二进制表达就是全1。16进制为:0xFFFFFF。

    计算机原理-原码、反码、补码

    更多内容:http://www.juqingshow.com/jsjyuanli/200701/7687.html

    首先要说的是:计算机中的带符号数一般用补码表示

    计算机中的带符号数用补码表示的优点:

    1、负数的补码与对应正数的补码之间的转换可以用同一种方法——求补运算完成,可以简化硬件;

    2、可将减法变为加法,省去减法器;

    3、无符号数及带符号数的加法运算可以用同一电路完成。

    带符号数的表示

    先引进两个名词:机器数和真值。

    将一个数在机器中的表示形式,即编码称为机器数,数的本身称为真值。平常我们经常用的带符号的数就是真数,如:+50,-10.5等等。

    常用的机器数有三种:原码、补码和反码。

    1.原码

    通俗定义

    将数的符号数码化,即用一个二进制位表示符号:对正数,该位取0,对负数,该位取1。

    而数值部分保持数的原有形式(有时需要在高位部分添几个0)。这样所得结果为该数的原码表示。

    例,x=+1001010,y= -1001010,z= 一1110(= 一0001110)。当原码为8位时,x、y和z的原码分别是:

    [x]原=01001010;

    [y]原=11001010;

    [Z]原=10001110.

    其中最高位为符号位。

    2)正规定义

    2.反码

    反码:正数的反码为原码,负数的反码是原码符号位外按位取反。

    例如:

    X1=+67=+100 0011B          ,[X1]反=0100 0011B X2=-67=-100 0011B          ,[X2]反=1011 1100B

    对正数,其反码与原码相同,也与补码相同。对负数,其反码等于原码除符号位外,按位求反(末位不加1)。利用反码也可使带符号数的加、减法转化为单纯的加法,但麻烦一些。

    一般把求反码作为求补的中间过程,即 [x]补=[x]反+1。

    3.补码

    1)补码的引进和定义

    据统计,在所有的运算中,加、减运算要占到80%以上,因此,能否方便地进行正、负数加、减运算,直接关系到计算机的运行效率。

    把一个负数加模的结果称为该负数的补码(结果是一个正数,它和该负数是等价的,确切地说,是一对一的,因而可看作是该负数的编码),定义正数的补码就是它本身,符号位取0,即和原码相同。这就是补码的通俗定义。将这个定义用数学形式表示出来,就可得到补码的正规定义:

    其中n为补码的位数。这个定义实际也将真值的范围给出来了,当n=8时,一27≤x<27。和原码相比,补码表示可多表示一个数。当n=8时,多表示的数是一27=一128。

    2)补码的求法

    对正数,补码同原码。

    例如,x=+0101001,[x]补=[x]原=00101001。

    对负数,由定义求补码,需做减法,不方便。经推导可知,负数的补码等于其原码除符号位外按位“求反”(1变0,0变1),末位再加1。

    例如,y=一0001100,[y]原=10001100,[Y]补=11110011+1=11110100。

    •算法:1.正数的补码与原码相同; 2.负数的补码由原码除符号位保持不变外,其余各位按位取反,再在末位加1。   [x]补=[x]反+1 •

    多做几例,可得出一种心算求补的方法——从最低位开始至找到的第一个1均不变,符号位不变,这之间的各位“求反”(该方法仅用于做题)。

    展开全文
  • short、int、long 是C语言中常用的种整数类型,分别称为短整型、整型、长整型。在现代操作系统中,short、int、long 的长度分别是 2、4、4 或者 8,它们只能存储有限的数值,当数值过大或者过小时,超出的部分会被...
  • SCAU 汇编实验 将寄存器中的无符号数有符号数进制、八进制、十六进制的形式输出1.将BX中的无符号数进制的形式输出2.将BX中的无符号数以八进制的形式输出3.将BX中的无符号数以十六进制的形式输出4.将BX中...
  • 在第一个示例中,使用移位来转换uint32_t. 基本上第32章整数到数组uint8_t并尝试访问每个字节和移位。uint32_t htonl(uint32_t x){uint8_t *s = (uint8_t*)&x;return (uint32_t)(s[0] << 24 | s[1]...
  • 我会用struct.import structdef toU32(bits):return struct.unpack_from(">I", bits)[0]def toS32(bits):return struct.unpack_from(">i", bits)[0]格式字符串“>...对于有符号整数,您可以使用“>...
  • 话题:16符号整数为什么是回答:剩下15位二进制的最大值是每一位数都是1的情况,即2^15-1=326.326化成进制为1000 0000 0000 0000,对于带符号整数来说就是-0.话题:关于C语言中有符号的整数值范围为什么是从...
  • c语言中,数值分为有符号数(signed) 和 无符号数(unsigned),有符号数区分正数和负数,无符号数只有正数,程序中如果不通过unsigned指定(如unsigned int x 来指定x为无符号数),则x默认为有符号数
  • 前言:近期在调试一个博世的三轴加速度传感器时,在用c写有符号数相关的运算和操作相关的代码时,进一步去理解了有符号数的应用。首先在阅读相关文档时,发现了对寄存器描述中出现Two's complement,实际是为了说明...
  • Fist:why?时候只知道什么还不够,我们还需要为什么,...整型数据结构(Integer)整型数据在计算机低层组织结构包括无符号数有符号数1.1 无符号数现在常见的编程语言中支持无符号数的只有C\C++,通过unsigned关键...
  • COMPOSE 求复合函数 COND (逆)条件 CONDEIG 计算特征值、特征向量同时给出条件 CONDEST 范 -1条件估计 CONJ 复数共轭 CONTOUR 等位线 CONTOURF 填色等位线 CONTOUR3 维等位线 CONTOURSLICE 维切片等位...
  • 【计组笔记-3】分析无符号数有符号数的计算区别1. 无符号数有符号数的定义2. 通过代码展示两者的区别3. 详细分析区别的产生原因3.1 无符号(unsigned)int型的...简单来讲,无符号数就是所有的进制都是数值
  • java 运算符号

    2021-03-05 22:20:06
    《道生一,一生二,二生,三生万物》出自老子的《道德经》第四十二章。主要讲述了一、二、这几个数字,并不把一、二、看作具体的事物和具体数量。它们只是表示“道”生万物从少到多,从简单到复杂的一个过程。...
  • 符号数:整个机器字长的全部进制均为数值,没有符号,相当于数的绝对值 如: 表示范围: 2048 1024 512 256 128 64 32 16 8...
  • 原文参考:... 小数部分0.5, 进制是.1,先把他们连起来,从第一个1起取24位(后面补0):1100.10000000000000000000这部分是有效数字。(把小数点前后两部分连起来再取掉头前的1,就是...
  • 1进制1101.1111转换成十六进应为()A.A.FB.E.FC.D.FD.A.E2进制110101对应的进制是()A.44B.65C.53D.743进制11011+1101等于()A.100101B.10101C.101000D.100114进制11101011-10000100等于()A....
  • 进制转换与运算

    2021-05-23 06:09:16
    进制“001”为例, 每一都是一个bit。进制只能由0/1组成,所以正好可以表示bit。什么是byte1个bit只能表示两种信号或者两种状态,表示的范围很小,例如英文字母26个就无法表示。所以规定8个bit一组作为一个...
  • 2)进制的简写形式、进制运算1)八进制运算表(1) 加法运算表(2)乘法运算表(3)八进制简单运算题、数据宽度1)什么是数据宽度2)计算机中常用的基本数据宽度、无符号数有符号数进制进制也就是进位计数制,是人为...
  • WORD为无符号16位二进制整数DWORD为无符号32位二进制整数LONG为32位二进制整数char占一个字节,8unsigned short2个字节16BYTE一个字节8符号数搞清楚概念:int是带符号数32位负数正数0x80000000(对应负数...
  • 有符号数在计算机中的表示方法

    千次阅读 2021-01-04 15:20:18
    最近因为要将一个16bit的音频混音算法改成24bit的,复习了有符号数的计算机内的表示方法. 对负数的进制表示有些遗忘,在网上找了一下资料,贴出来已备再次遗忘: 假设一个 int 类型的数,值为5,那么,我们...
  • C1 48 00 00 从这个例子可以得到下面的信息: 符号位是1 表示一个负数 幂是进制10000010或进制130,130减去127是3,就是实际的幂。 尾数是后面的进制10010000000000000000000 在尾数的左边一个省略的...
  • 数位进制转换详解

    千次阅读 2021-01-16 20:24:26
    十二位 第十一位 第十位 第九位 第八位 第七位 第六位 第五位 第位 第位 第二位 第一位 2048 1024 512 256 128 64 32 16 8 4 2 1 注意:权数是以十进制来表示的,相邻是两倍的关系,最大的权数必须...
  • 在上一篇文章中,我们大致了解了一下有符号数,无符号数的概念,接下来将通过几道题来加深对它们的了解! 题一:
  • 进制乘法可分为两种情况:无符号数乘法和有符号数乘法。 无符号数乘法示例如下: 有符号数的正数乘负数示例如下: 有符号数的负数乘负数示例如下: 由上述示例,我们可以得出结论,若两乘数的位宽分别a,b,...
  • 符号数有符号数是不能进行比较运算的,否则可能会出现意想不到的错误,且极难检查出来!首先肯几个例子(假设在32位的机器上):1 1. 0 == 0U2 2. -1 < 0U (注: 0是无符号的)3 3. 2147483647U > -...
  • 我需要读取无符号8值,无符号16值和无符号32位值的方法.这样做的最佳(最快,最好看的代码)是什么?我在c中完成了这个并做了类似这样的事情:uint8_t *buffer;uint32_t value = buffer[0] | buffer[1] << 8 |...
  • 现代计算机都是基于 0、1两个符号表示信息的,即现代计算机中数值的表示是进制。 进制的定义 进制:进位计数制的简称,指针的方法,一般用于刻画实物之间的数量关系,是人们长期实践中发现和发明的。 进制 ...
  • python 把16进制字符串转化为16进制数字, 比如‘0x小编不希望一天发现自己是为了别人活,小编愿意承担后果,就算偶尔寂寞甚至孤独而终,小编都能接受。十六进制的ascii码怎么成十六进制呢?(python)如何让python...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 185,447
精华内容 74,178
关键字:

有符号数24位转32位