精华内容
下载资源
问答
  • 确如题主所说,计算机中存储的任何数据都是二进制形式,单看数据是无法认定其格式和内容的。 计算机要用二进制编码来表达...先看8位二进制与无符号数和有符号数的对应二进制 无符号 有符号 00000000 0 000000001 1 1

    确如题主所说,计算机中存储的任何数据都是二进制形式,单看数据是无法认定其格式和内容的。

    计算机要用二进制编码来表达数值的符号,最直观的方法就是符号位。但为了保证基本算术运算在正负数上的一致性,x86计算机对负数采用了特殊的编码方式,即补码。

    为什么补码这么巧妙实现了正负数的加减运算?参见维基百科:
    补码
    -1的二进制表示

    下面结合题主提到的寄存器状态举个例子。
    为简化起见,我们8位二进制数来讲。
    先看8位二进制与无符号数和有符号数的对应二进制
    无符号 有符号
    00000000 0 000000001 1 1

    01111110 126 126
    01111111 127 127
    10000000 128 -128
    10000001 129 -127

    11111110 254 -2
    11111111 255 -1

    按照上述对应关系,我们可以把二进制运算解释为有符号或无符号的十进制运算。
    只有算术运算才会有正负号问题,而算术运算中最主要的就是加法系列指令和减法系列指令。

    范围内的运算咱们不关心,主要看看超出范围的运算如何处理。
    当运算超出范围后,CPU会改变标志寄存器中的值(置1),来表示当前的运算结果。

    算术运算主要用到的标志位如下。
    OV(溢出):运算结果超过数值表达范围(比如8位数运算超过256);
    ZR(零):运算结果为0时;
    PL(符号):运算结果的最高位为1。
    AC(辅助进位):低4位是否向高4位进/借位;
    CY(进位):高位进/借位;

    1. 当加法系指令的二进制结果大于11111111时会产生溢出,结果保留超过11111111的部分,并置溢出位为1。例如加法add指令:11111110+00000011=100000001=>00000001
      标志位:
      由于低4位和高4位都进位了,所以AC和CY置1
      对应的无符号运算:
      254+3=1
      对应的有符号运算:
      -2+3=1

    2. 减法系的指令会产生“减不过”的情况。
      减不过时cpu会给左数的最高位添加一个1,使得比右数大,再做减法并置溢出。
      例如减法sub指令:
      00000010-00000011=>100000010-00000011=11111111
      标志位:
      由于低4位和高4位都借位了,所以AC和CY置1,由于运算结果高位为1,PL置1
      对应的无符号运算:
      2-3=255
      对应的有符号运算:
      2-3=-1

    其他的算术运算较复杂,但都可以用类似的方法分析。因超出问题范围,此处不再赘述。

    展开全文
  • 这个问题我在学习汇编语言的过程中一直很苦恼,在网上看了很多帖子,基本上都是说是人自己设定是有符号数还是无符号数的。这样的回答是很扯淡的,TM计算机和人脑又不是一个东西,看来很多人学东西基本上都是一知半解...

    这个问题我在学习汇编语言的过程中一直很苦恼,在网上看了很多帖子,基本上都是说是人自己设定是有符号数还是无符号数的。这样的回答是很扯淡的,TM计算机和人脑又不是一个东西,看来很多人学东西基本上都是一知半解,这样无疑是idot。反复搜了好几个帖子,终于发现了一个比较靠谱的大佬说出了有符号数和无符号数的区别:

    有符号数和无符号数探讨   

    这个问题,要是简单的理解,是很容易的,不过要是考虑的深了,还真有些东西呢。
    下面我就把这个东西尽量的扩展一点,深入一点和大家说说。
     
    一、只有一个标准!
     
    在汇编语言层面,声明变量的时候,没有 signed 和 unsignde 之分,汇编器统统,将你输入的整数字面量当作有符号数处理成补码存入到计算机中,只有这一个标准!汇编器不会区分有符号还是无符号然后用两个标准来处理,它统统当作有符号的!并且统统汇编成补码!也就是说,db -20 汇编后为:EC ,而 db 236 汇编后也为 EC 。这里有一个小问题,思考深入的朋友会发现,db 是分配一个字节,那么一个字节能表示的有符号整数范围是:-128 ~ +127 ,那么 db 236 超过了这一范围,怎么可以?是的,+236 的补码的确超出了一个字节的表示范围,那么拿两个字节(当然更多的字节更好了)是可以装下的,应为:00 EC,也就是说 +236的补码应该是00 EC,一个字节装不下,但是,别忘了“截断”这个概念,就是说最后汇编的结果被截断了,00 EC 是两个字节,被截断成 EC ,所以,这是个“美丽的错误”,为什么这么说?因为,当你把 236 当作无符号数时,它汇编后的结果正好也是 EC ,这下皆大欢喜了,虽然汇编器只用一个标准来处理,但是借用了“截断”这个美丽的错误后,得到的结果是符合两个标准的!也就是说,给你一个字节,你想输入有符号的数,比如 -20 那么汇编后的结果是符合有符号数的;如果你输入 236 那么你肯定当作无符号数来处理了(因为236不在一个字节能表示的有符号数的范围内啊),得到的结果是符合无符号数的。于是给大家一个错觉:汇编器有两套标准,会区分有符号和无符号,然后分别汇编。其实,你们被骗了。:-)
     
    二、存在两套指令!
     
    第一点说明汇编器只用一个方法把整数字面量汇编成真正的机器数。但并不是说计算机不区分有符号数和无符号数,相反,计算机对有符号和无符号数区分的十分清晰,因为计算机进行某些同样功能的处理时有两套指令作为后备,这就是分别为有符号和无符号数准备的。但是,这里要强调一点,一个数到底是有符号数还是无符号数,计算机并不知道,这是由你来决定的,当你认为你要处理的数是有符号的,那么你就用那一套处理有符号数的指令,当你认为你要处理的数是无符号的,那就用处理无符号数的那一套指令。加减法只有一套指令,因为这一套指令同时适用于有符号和无符号。下面这些指令:mul div movzx … 是处理无符号数的,而这些:imul idiv movsx … 是处理有符号的。
    举例来说:
    内存里有 一个字节x 为:0x EC ,一个字节 y 为:0x 02 。当把x,y当作有符号数来看时,x = -20 ,y = +2 。当作无符号数看时,x = 236 ,y = 2 。下面进行加运算,用 add 指令,得到的结果为:0x EE ,那么这个 0x EE 当作有符号数就是:-18 ,无符号数就是 238 。所以,add 一个指令可以适用有符号和无符号两种情况。(呵呵,其实为什么要补码啊,就是为了这个呗,:-))
    乘法运算就不行了,必须用两套指令,有符号的情况下用imul 得到的结果是:0x FF D8 就是 -40 。无符号的情况下用 mul ,得到:0x 01 D8 就是 472 。(参看文后附录2例程)
     
    三、可爱又可怕的c语言。
     
    为什么又扯到 c 了?因为大多数遇到有符号还是无符号问题的朋友,都是c里面的 signed 和 unsigned 声明引起的,那为什么开头是从汇编讲起呢?因为我们现在用的c编译器,无论gcc 也好,vc6 的cl 也好,都是将c语言代码编译成汇编语言代码,然后再用汇编器汇编成机器码的。搞清楚了汇编,就相当于从根本上明白了c,而且,用机器的思维去考虑问题,必须用汇编。(我一般遇到什么奇怪的c语言的问题都是把它编译成汇编来看。)
     
    C 是可爱的,因为c符合kiss 原则,对机器的抽象程度刚刚好,让我们即提高了思维层面(比汇编的机器层面人性化多了),又不至于离机器太远(像c# ,java之类就太远了)。当初K&R 版的c就是高级一点的汇编……:-)
     
    C又是可怕的,因为它把机器层面的所有的东西都反应了出来,像这个有没有符号的问题就是一例(java就不存在这个问题,因为它被设计成所有的整数都是有符号的)。为了说明它的可怕特举一例:
     
    #include <stdio.h> 
    #include <string.h> 
     
    int main()
    {
        int x = 2; 
        char * str = "abcd"; 
        int y = (x - strlen(str) ) / 2;
        
        printf("%d\n",y);
    }
     
    结果应该是 -1 但是却得到:2147483647 。为什么?因为strlen的返回值,类型是size_t,也就是unsigned int ,与 int 混合计算时有符号类型被自动转换成了无符号类型,结果自然出乎意料。。。
    观察编译后的代码,除法指令为 div ,意味无符号除法。
    解决办法就是强制转换,变成 int y = (int)(x - strlen(str) ) / 2; 强制向有符号方向转换(编译器默认正好相反),这样一来,除法指令编译成 idiv 了。
    我们知道,就是同样状态的两个内存单位,用有符号处理指令 imul ,idiv 等得到的结果,与用 无符号处理指令mul,div等得到的结果,是截然不同的!所以牵扯到有符号无符号计算的问题,特别是存在讨厌的自动转换时,要倍加小心!(这里自动转换时,无论gcc还是cl都不提示!!!)
     
    为了避免这些错误,建议,凡是在运算的时候,确保你的变量都是 signed 的。
     
    四、c的做法。
     
    对于有符号和无符号的处理上,c语言层面做的更“人性化”一些。比如在声明变量的时候,c 有signed 和 unsigned 前缀来区别,而汇编呢,没有任何区别,把握全在你自己,比如:你想在一个字节中输入一个有符号数,那么这个数就别超过 -128 ~ +127 ,想输入无符号数,要保证数值在 0~255 之间。如果你输入了 236 ,你还要说你输入的是有符号数,那么你肯定错了,因为有符号数236至少要两个字节来存放(为00 EC),不要小看了那一个字节的00,在有符号乘法下,两个字节的00 EC 与 一个字节的EC,在与同样一个数相乘时,得到的结果是截然不同的!!!
     
    我们来看下具体的列子(用vc6的cl编译器生成):
     
    C语言 编译后生产的汇编语言 
           ……
           char x;
           unsigned char y;
           int z;
           
           x = 3;
           y = 236;
     
           z = x*y;
           ……        ……
           _x$ = -4
           _y$ = -8
           _z$ = -12
           …… 
           mov BYTE PTR _x$[ebp], 3
           mov BYTE PTR _y$[ebp], 236     
     
           movsx    eax, BYTE PTR _x$[ebp]
           mov ecx, DWORD PTR _y$[ebp]
           and ecx, 255 
                  
           imul eax, ecx
           mov DWORD PTR _z$[ebp], eax
           …… 


     
    我们看到,在赋值的时候(绿色部分),汇编后与本文第一条论述相同,是否有符号把握全在自己,c比汇编做的更好这一点没有得到体现,这也可以理解,因为c最终要被编译成汇编,汇编没有在变量声明时区分有无符号这一功能,自然,c也没有办法。但既然c提供了signed和unsigned声明,汇编后,肯定有代码体现这一点,表格里的红色部分就是。对有符号数x他进行了符号扩展,对无符号y进行了零扩展。这里为了举例的方便,进行了有符号数和无符号数的混合运算,实际编程中要避免这种情况。
     
    (完)
     
     
    附录:
     
    1.计算机对有符号整数的表示只采取一套编码方式,不存在正数用原码,负数用补码这用两套编码之说,大多数计算机内部的有符号整数都是用补码,就是说无论正负,这个计算机内部只用补码来编码!!!只不过正数和0的补码跟他原码在形式上相同,负数的补码在形式上与其绝对值的原码取反加一相同。
     
    2. 两套乘法指令结果例程:
     
    ;; 程序存储为 x.s
     
    extern printf 
    global main 
     
    section .data
        str1: db "%x",0x0d,0x0a,0 
        n: db 0x02
    section .text 
    main: 
        xor eax,eax
        mov al, 0xec
        mul byte [n] ;有符号乘法指令为: imul
     
        push eax
        push str1
        call printf 
        
        add esp,byte 4 
        ret 
        
    编译步骤:
    1. nasm -felf x.s 
    2. gcc x.o
     
    ubuntu7.04 下用nasm和gcc编译通过。结果符合文章所述---------------------------文章未经允许不得转载
    ————————————————
    版权声明:本文为CSDN博主「特斯拉的电流原」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_33268859/article/details/86794550

    展开全文
  • 这个问题我在学习汇编语言的过程中一直很苦恼,在网上看了很多帖子,基本上都是说是人自己设定是有符号数还是无符号数的。这样的回答是很扯淡的,TM计算机和人脑又不是一个东西,看来很多人学东西基本上都是一知半解...

    这个问题我在学习汇编语言的过程中一直很苦恼,在网上看了很多帖子,基本上都是说是人自己设定是有符号数还是无符号数的。这样的回答是很扯淡的,TM计算机和人脑又不是一个东西,看来很多人学东西基本上都是一知半解,这样无疑是idot。反复搜了好几个帖子,终于发现了一个比较靠谱的大佬说出了有符号数和无符号数的区别:

    有符号数和无符号数探讨   

    这个问题,要是简单的理解,是很容易的,不过要是考虑的深了,还真有些东西呢。
    下面我就把这个东西尽量的扩展一点,深入一点和大家说说。
     
    一、只有一个标准!
     
    在汇编语言层面,声明变量的时候,没有 signed 和 unsignde 之分,汇编器统统,将你输入的整数字面量当作有符号数处理成补码存入到计算机中,只有这一个标准!汇编器不会区分有符号还是无符号然后用两个标准来处理,它统统当作有符号的!并且统统汇编成补码!也就是说,db -20 汇编后为:EC ,而 db 236 汇编后也为 EC 。这里有一个小问题,思考深入的朋友会发现,db 是分配一个字节,那么一个字节能表示的有符号整数范围是:-128 ~ +127 ,那么 db 236 超过了这一范围,怎么可以?是的,+236 的补码的确超出了一个字节的表示范围,那么拿两个字节(当然更多的字节更好了)是可以装下的,应为:00 EC,也就是说 +236的补码应该是00 EC,一个字节装不下,但是,别忘了“截断”这个概念,就是说最后汇编的结果被截断了,00 EC 是两个字节,被截断成 EC ,所以,这是个“美丽的错误”,为什么这么说?因为,当你把 236 当作无符号数时,它汇编后的结果正好也是 EC ,这下皆大欢喜了,虽然汇编器只用一个标准来处理,但是借用了“截断”这个美丽的错误后,得到的结果是符合两个标准的!也就是说,给你一个字节,你想输入有符号的数,比如 -20 那么汇编后的结果是符合有符号数的;如果你输入 236 那么你肯定当作无符号数来处理了(因为236不在一个字节能表示的有符号数的范围内啊),得到的结果是符合无符号数的。于是给大家一个错觉:汇编器有两套标准,会区分有符号和无符号,然后分别汇编。其实,你们被骗了。:-)
     
    二、存在两套指令!
     
    第一点说明汇编器只用一个方法把整数字面量汇编成真正的机器数。但并不是说计算机不区分有符号数和无符号数,相反,计算机对有符号和无符号数区分的十分清晰,因为计算机进行某些同样功能的处理时有两套指令作为后备,这就是分别为有符号和无符号数准备的。但是,这里要强调一点,一个数到底是有符号数还是无符号数,计算机并不知道,这是由你来决定的,当你认为你要处理的数是有符号的,那么你就用那一套处理有符号数的指令,当你认为你要处理的数是无符号的,那就用处理无符号数的那一套指令。加减法只有一套指令,因为这一套指令同时适用于有符号和无符号。下面这些指令:mul div movzx … 是处理无符号数的,而这些:imul idiv movsx … 是处理有符号的。
    举例来说:
    内存里有 一个字节x 为:0x EC ,一个字节 y 为:0x 02 。当把x,y当作有符号数来看时,x = -20 ,y = +2 。当作无符号数看时,x = 236 ,y = 2 。下面进行加运算,用 add 指令,得到的结果为:0x EE ,那么这个 0x EE 当作有符号数就是:-18 ,无符号数就是 238 。所以,add 一个指令可以适用有符号和无符号两种情况。(呵呵,其实为什么要补码啊,就是为了这个呗,:-))
    乘法运算就不行了,必须用两套指令,有符号的情况下用imul 得到的结果是:0x FF D8 就是 -40 。无符号的情况下用 mul ,得到:0x 01 D8 就是 472 。(参看文后附录2例程)
     
    三、可爱又可怕的c语言。
     
    为什么又扯到 c 了?因为大多数遇到有符号还是无符号问题的朋友,都是c里面的 signed 和 unsigned 声明引起的,那为什么开头是从汇编讲起呢?因为我们现在用的c编译器,无论gcc 也好,vc6 的cl 也好,都是将c语言代码编译成汇编语言代码,然后再用汇编器汇编成机器码的。搞清楚了汇编,就相当于从根本上明白了c,而且,用机器的思维去考虑问题,必须用汇编。(我一般遇到什么奇怪的c语言的问题都是把它编译成汇编来看。)
     
    C 是可爱的,因为c符合kiss 原则,对机器的抽象程度刚刚好,让我们即提高了思维层面(比汇编的机器层面人性化多了),又不至于离机器太远(像c# ,java之类就太远了)。当初K&R 版的c就是高级一点的汇编……:-)
     
    C又是可怕的,因为它把机器层面的所有的东西都反应了出来,像这个有没有符号的问题就是一例(java就不存在这个问题,因为它被设计成所有的整数都是有符号的)。为了说明它的可怕特举一例:
     
    #include <stdio.h> 
    #include <string.h> 
     
    int main()
    {
        int x = 2; 
        char * str = "abcd"; 
        int y = (x - strlen(str) ) / 2;
        
        printf("%d\n",y);
    }
     
    结果应该是 -1 但是却得到:2147483647 。为什么?因为strlen的返回值,类型是size_t,也就是unsigned int ,与 int 混合计算时有符号类型被自动转换成了无符号类型,结果自然出乎意料。。。
    观察编译后的代码,除法指令为 div ,意味无符号除法。
    解决办法就是强制转换,变成 int y = (int)(x - strlen(str) ) / 2; 强制向有符号方向转换(编译器默认正好相反),这样一来,除法指令编译成 idiv 了。
    我们知道,就是同样状态的两个内存单位,用有符号处理指令 imul ,idiv 等得到的结果,与用 无符号处理指令mul,div等得到的结果,是截然不同的!所以牵扯到有符号无符号计算的问题,特别是存在讨厌的自动转换时,要倍加小心!(这里自动转换时,无论gcc还是cl都不提示!!!)
     
    为了避免这些错误,建议,凡是在运算的时候,确保你的变量都是 signed 的。
     
    四、c的做法。
     
    对于有符号和无符号的处理上,c语言层面做的更“人性化”一些。比如在声明变量的时候,c 有signed 和 unsigned 前缀来区别,而汇编呢,没有任何区别,把握全在你自己,比如:你想在一个字节中输入一个有符号数,那么这个数就别超过 -128 ~ +127 ,想输入无符号数,要保证数值在 0~255 之间。如果你输入了 236 ,你还要说你输入的是有符号数,那么你肯定错了,因为有符号数236至少要两个字节来存放(为00 EC),不要小看了那一个字节的00,在有符号乘法下,两个字节的00 EC 与 一个字节的EC,在与同样一个数相乘时,得到的结果是截然不同的!!!
     
    我们来看下具体的列子(用vc6的cl编译器生成):
     
    C语言 编译后生产的汇编语言 
           ……
           char x;
           unsigned char y;
           int z;
           
           x = 3;
           y = 236;
     
           z = x*y;
           ……        ……
           _x$ = -4
           _y$ = -8
           _z$ = -12
           …… 
           mov BYTE PTR _x$[ebp], 3
           mov BYTE PTR _y$[ebp], 236     
     
           movsx    eax, BYTE PTR _x$[ebp]
           mov ecx, DWORD PTR _y$[ebp]
           and ecx, 255 
                  
           imul eax, ecx
           mov DWORD PTR _z$[ebp], eax
           …… 


     
    我们看到,在赋值的时候(绿色部分),汇编后与本文第一条论述相同,是否有符号把握全在自己,c比汇编做的更好这一点没有得到体现,这也可以理解,因为c最终要被编译成汇编,汇编没有在变量声明时区分有无符号这一功能,自然,c也没有办法。但既然c提供了signed和unsigned声明,汇编后,肯定有代码体现这一点,表格里的红色部分就是。对有符号数x他进行了符号扩展,对无符号y进行了零扩展。这里为了举例的方便,进行了有符号数和无符号数的混合运算,实际编程中要避免这种情况。
     
    (完)
     
     
    附录:
     
    1.计算机对有符号整数的表示只采取一套编码方式,不存在正数用原码,负数用补码这用两套编码之说,大多数计算机内部的有符号整数都是用补码,就是说无论正负,这个计算机内部只用补码来编码!!!只不过正数和0的补码跟他原码在形式上相同,负数的补码在形式上与其绝对值的原码取反加一相同。
     
    2. 两套乘法指令结果例程:
     
    ;; 程序存储为 x.s
     
    extern printf 
    global main 
     
    section .data
        str1: db "%x",0x0d,0x0a,0 
        n: db 0x02
    section .text 
    main: 
        xor eax,eax
        mov al, 0xec
        mul byte [n] ;有符号乘法指令为: imul
     
        push eax
        push str1
        call printf 
        
        add esp,byte 4 
        ret 
        
    编译步骤:
    1. nasm -felf x.s 
    2. gcc x.o
     
    ubuntu7.04 下用nasm和gcc编译通过。结果符合文章所述---------------------------文章未经允许不得转载

    展开全文
  • 1.计算机内存中存放的数值型数据都是补码形式的; 2.CPU根本不区分有符号数值还是无符号...5.有符号数的加减法,CUP只会设置相应的进位标志寄存器和溢出标志寄存器, 由程序员(汇编程序员)或高级程序语言编译器决定
    1.计算机内存中存放的数值型数据是由编译器处理后保存的;

    2.CPU根本不区分有符号数值还是无符号数值,CPU按照相同的运输规律进行计算,并设置相关Flags位,由程序自己决定解释是有符号运算还是无符号运算;

    3.如果应用程序逻辑标示的是负数,则编译器送入CPU寄存器的数值都是补码形式标示;

    4.引入补码的原因是:
    一是:CPU将加,减法统一为加法运算;
    二是:补码对加、减、移位等操作具有幂等性。

    5.有符号数的加减法,CUP只会设置相应的进位标志寄存器和溢出标志寄存器,
    由程序员(汇编程序员)或高级程序语言编译器决定将进位作为符号位,还是数值位;

    6.有符号数和无符号数的乘除法,CUP有不同的指令分别处理;

    7.CPU可以有硬件阵列乘法器或除法器,

      也可以通过加减,与,或,非,异或等模拟乘除运算。

    ---------------------------------------------------------------------------

    书中写到: 
    mov al,10000001B 
    add al,1 
    可以将add指令进行的运算当作无符号数的运算,也可以将add指令进行的运算当作有符号数的运算。 

    问题: 
    到底是当作有符号还是无符号数。 

    我认为:执行了上面两条指令后,SF标志值肯定是一定的。所以有无符号运算也是定好的。问题就是,我怎么知道进行的是有符号运算还是无符号运算。 

    请指点,谢谢。
    ######################################################
    CPU处理一个二进制数时,其实也无法知道这个数是有符号还是无符号数;
    由于引入了补码,使得加减计算的指令对有符号数和无符号数的处理是一样的,
    所以加减运算时CPU将运算结果作为有符号数和无符号数对符号位的影响都“罗列”出来了,
    供编程者根据需要使用;乘除运算有符号数和无符号数所用的指令是不同的。 
    那么如何判断一个数究竟是有符号数还是无符号数呢?如果程序(本质上是编程者)
    把最高位用作符号位,这就是有符号数;如果把最高位作为有效数位,那就是无符号数了。
        
    cpu在执行add等指令时,是必然要影响到SF标志位的值的。至于我们需不需要这种影响,那就看我们如何看待指令所进行
    的运算了。 也就是说,到底是有符号数还是无符号数,是有我们来决定的。

    这个sf为正还是为负实际上就是计算机运算后给符号位定一个值,是1还是0,我明白了,
    在附注的补码中就是说,当最高位为1就代表负数,那么就是当计算后数第一个数为1时,sf也就是1了

    #######################################################
    在汇编语言里面:
    加减其实不分是有符号还是无符号的,主要依靠用户自己判断,
    在进行完加减操作以后,对CF, OF两个寄存器进行判断,如有无近位和溢出。
    而在乘除计算的时候,则有相应的不同的机器代码对计算数字进行不同的处理。

    对于高级语言C,由编译器根据源程序做出判断是有符号还是无符号,再翻译成汇编程序处理;

    ##################################
    对于乘除法:CPU有不同的指令
    读与加减:CPU按照统一格式进行处理,
    原因是有无符号运算结构一致(原因是计算机采用补码进行运算决定的)










    展开全文
  • 有符号数和无符号数

    2014-04-21 22:57:00
    认识有符号数和无符号数   说起有符号数和无符号数,就不得不提到原码、反码和补码,那我们就从他们开始说起吧。  一个数在计算机中的二进制表示形式, 叫做这个数的机器数,机器数是以补码形式储存在计算机中的...
  • 原理:当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。实例代码:#include #include int main(){int i=100;int j=-1;if(i<0){printf("i 是有符号...如果i是有符号数,则j应该比i小...
  • 有符号数和无符号数详解(2)补码详解1. 为什么需要补码1.1 背景2 补码的思想2.1 我们希望只设计加法运算器,不用减法运算器。2.2 现在问题是:怎么表示-1呢?3. 补码3.1 补码的优点3.2 例子:4. 补码的本质:参考 1...
  • 一个数据在计算机中存储是以01方式存储的,怎么表示有符号与无符号呢,很简单,数据类型的最高位用于标识数据的符号 最高位为1,表明这个为负数 最高位为0,表明这个为正数 //2-1.c #include <stdio.h> ...
  • 1 首先我们应该明白计算机对于数字的加减运算其实是一种运算,在计算机中只有加法运算,因为计算机只是实现了加法器。...于是规定所有位数上都是0的数字是0.16位的16位都是0,32位的数字32位都是0. ...
  • 在leetcode上刷第七题时,提到32位的有符号二进制数表示的整数范围为:-2^31~2^31-1,那这是怎么来的呢...对于有符号数,最高位用来表示该整数的符号,0表示正数,1表示负数。 如果是正数,直接将它的原码翻译成十进...
  • 在做协议传输时,通常...但是有些数据是有符号数格式的,比如水位数据,水位数据的真实值等于水位基值+水位传感器测量值,按照协议要求,水位的取值范围是-7999到+7999,当我们计算出负值的时候应该怎么转换呢? ...
  • 在搭建乘法器,验证波形时,多比特二进制手算比较麻烦,所以导入matlab计算正确的输出结果。 此时要注意乘法器的特性,举个例子吧 5 × 5 = 25 也就是4‘b0101(+5) * 4’b0101(+5) = 0011001(+25) 那 -5 × 5 = -...
  • 一个很长的字符串,里面字母数字标点符号汉字,怎么写一段代码计算汉字的个数
  • 于是想上网查查怎么回事, 结果看了很久都没有得到一个满意的答案。 书上这么一段话:当将一个超出数据类型取值范围的值赋值给这个类型的一个变量时,变量的值的结果由变量的 类型决定。 后面还有这么一段...
  • 有符号与无符号

    2018-03-15 11:23:56
    1、计算机中的符号位 有符号编码规则:数据的最高位用于标识数据的符号 -最高位为1,表示这个数为负数 - 最高位为0,表示这个数为正数 无符号编码规则:数据的最高位不...有符号数的符号位 2-1.c #inclu...
  • 例如8bit有符号数:-128 ~ +127,及其原码补码,本文会非常清楚地讲一下这个范围是怎么来的以及它们的原码补码 最高位为符号位,0代表正数,1代表负数,正数原码和补码相同,负数的补码是原码符号位不变其他位取反...
  • 比如阶码小于偏移值的时候怎么计算? 最好能给个例子,请各位帮助解答,谢谢。
  • C语言中有符号与无符号

    千次阅读 2018-04-13 18:04:42
    现在我们来分析下C语言中的有符号数与无符号数。我们知道,计算机只能识别二进制0和1,那么我们在程序中写的-12,计算机该怎么去识别这个"-"号?计算机怎么知道我们写的数,是正数还是负数?现在就一起来...
  • 面对未知,我们大多数人都选择了默认接受,其实你不懂根号2,比如:根号2(√2)为什么是无理,我们什么办法去计算它。当我冒出这个想法的时候,其实大部分人的反映都一样1+1开根号就是啊,至于为什么,就是...
  • c语言深度剖析(2)—有符号与无符号

    千次阅读 2019-08-30 20:16:37
    1.数据类型 1.1 计算机中的符号位 有符号编码规则:数据的最高位用于标识数据的符号 最高位为1,表示这个数为负数 ...有符号数的符号位 #include <stdio.h> int main() { char c = -5...
  • 数据类型 1.1 计算机中的符号位 有符号编码规则:数据的最高位用于标识数据的符号 最高位为1,表示这个数为负数 ...有符号数的符号位 #include <stdio.h> int main() { char c = -5; short s = 6; int ...
  • 有符号数:一个字节占8位,有符号就是有正有负,那么这8位就得有一位表示正号和负号,剩下七位数才表示数值。 无符号数:一个字节占8位,既然是无符号数,就是肯定是正的,这8位数都是数值位,对应C语言中的...
  • 在计算机中的表示

    2017-08-08 21:55:00
    比如:有符号数,符号位占一位,其他位为有效数据位。 确定负数的值:以一个字节为例,最高位为1表示负数。它的值为9位1 0000 0000(256)减去负数的位组合。 如:1000 0000;它表示一个负数,数值为1 0000 0000 -...
  • 定点数与浮点数定点数定点数的表示无符号数 : 没有符号位,全是数值位有符号数 (原码,补码,反码,移码)移码 : 在无符号数的基础上增加一个偏移值定点数的运算 : 小数是怎么存放的呢?移位加减溢出判断乘除强制类型转换 ...
  • 只说最精华的: ...3. 有符号型和无符号型变量的区别在于二进制首位是否作为符号位:有符号型,首位最为符号位,0表示正,1表示负; 无符号型,首位和其他位一样作为数字位。 4. C语言中,变量...
  • 原码、反码与补码,怎么计算

    千次阅读 2020-07-09 11:58:02
    也可以计算为:以原码进行操作,符号位不变,保持为1,其余位取反,直到碰到最后一个1为止,那个1及以后的数字不再取反。又:原码的第一个1和最后一个1之间的数字,全部取反。 举例说明:16位机,十进...

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 298
精华内容 119
关键字:

有符号数怎么计算