精华内容
下载资源
问答
  • C语言输出负数补码

    万次阅读 2017-06-06 22:35:00
    C语言打印出负数补码 最近刚好复习到计组的定点数运算,想着以前写快速幂都是打印出正数的补码,从来没有打印过负数的补码,于是写了几行代码,加深对这方面的理解。要知道的知识 数值在计算机表示为补码表示,所以...

    C语言输出负数补码

    最近刚好复习到计组的定点数运算,想着以前写快速幂都是打印出正数的补码,从来没有输出过负数的补码,于是写了几行代码,加深对这方面的理解。


    要知道的知识

    • 数值在计算机表示为补码表示,所以在C语言里负数也是以补码存储的
    • 了解算术移位和逻辑移位的区别
    • 在第三版的神书CSAPP里面提到

      c语言标准并没有明确定义对于有符号数使用哪种类型的右移。不幸地,这就意味着任何假设一种或者另一种右移形式的代码都可能会遇到可移植性问题。然而,实际上,几乎所有的编译器/机器组合都对有符号数使用算术右移,且许多程序员也都假设机器会使用这种右移。另一方面,对于无符号数,右移必须是逻辑的

    • 任何二进制在机器表示都是一样的,只是c语言的不同类型对其解释不一样。unsigned 类型将最高位解读为数值位,但是像short,int之类的就把最高位解读为符号位。

    代码

    要想打印出负数的补码,只对负数右移是不行的,因为它进行的是算术右移,这样最终只会无穷无尽地右移为-1,那么我们就可以先把有符号转化为无符号,因为二进制是一样的,只不过无符号和有符号对二进制解读不一样,于是很快写出下面几行小代码

    #include <cstdio>
    
    int main()
    {
        int num[20], cnt = 0;
        short a = -4321;
        unsigned short b = a;
        printf("%d\n", b);
        while(b)
        {
            num[cnt++] = b & 1;
            b >>= 1;
        }
        for(int i = cnt - 1; i >= 0; i--)
            printf("%d ", num[i]);//结果可与2018王道计组复习P45页对比
        return 0;
    }
    
    展开全文
  • 补码与反码在计算机中对数据进行运算操作时,符号位该如何表示呢?是否也同数值位一道参加运算操作呢??如果参加,会给运算操作带来什么影响呢???为了妥善地处理好这些问题,就产生了把 符号位 和 数值位 一起来...

    补码与反码

    在计算机中对数据进行运算操作时,

    符号位该如何表示呢?

    是否也同数值位一道参加运算操作呢??

    如果参加,会给运算操作带来什么影响呢???

    为了妥善地处理好这些问题,就产生了把 符号位 和 数值位 一起来编码来表示相应的数的各种表示方法,如原码、补码、反码、移码。

    为了区别一般书写表示的数和机器中这些编码表示的数,通常将前者称为 真值 ,后者称为 机器数或者机器码(带符号的)

    机器数或者机器码(最高位存放符号,正数0 负数1)

    (以+1 -1为例)00000001 10000001

    真值

    比如 00001010的真值为= +000 0001 =+10

    废话不多说,下面讲解一下 原码 补码 和 反码,不足之处望指正。

    原码:原码(true form)是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位表示数值的大小。{整数}

    /*十进制转换为二进制*/ #include int main(){ int n,x=0,a[1000]; printf("请输入转换的数:\n"); scanf("%d",&n); while(n) { a[x++]=n%2; n/=2; } --x; printf("其二进制数为:\n"); while(x>=0) printf("%d",a[x--]); }

    比如+10(正10) 首先转化为8位二进制 为 00001010 其原码为 0001010

    -10(负10) 其原码为10001011

    原码的缺点:不能直接参加运算,易出错

    such as :1+(-1)= 0

    如果用其原码参与运算,过程如下

    0000 0001+1000 0001=1000 0010 换算成10进制结果为 -2 结果是错误的

    反码:原码变反码很容易实现 (最高位为符号位)

    -------------------------正数的反码是其本身 负数的反码是在其原码的基础上,符号位不变,其余各位取反

    例子

    原码 --------->>>反码

    +1

    0000 0001--------->>>0000 0001

    -1

    1000 0001--------->>>1111 1110

    补码:在计算机系统中,数值一律用补码来表示和存储。可以将符号位和数值位统一处理。

    {

    正数的补码就是其本身,

    负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1 (即在反码的基础上+1)

    }

    就以钟表为例 现在为标准时间3点整 可是有一只表已经7点了,为了校准时间,可以有两种方法 ① 时针逆时针退7-3=4格 ② 时针顺时针向前拨 12-4=8格 此时还可以用 数学表达式(同余式) -4 = +8 来表示

    -4 = +8(mod 12) 有兴趣的童鞋可以详细看看数学!!!

    》》》此时咱们可以讨论一下char类型,范围的问题。。。

    - 众所周知char的范围类型为 -128~127,那这是为什么那是这个范围呢?

    - 八位 (八个bit占位)最大(1111 1111)即0到255之间的数 共有256个数

    - 同时我们也要存负数 所以128对 即最大是-128~128

    - 但是 但是 但是 规定1000 0000 为-128

    - 所以取值范围为-128~127(超过这个范围的 以补码形式存储 显示)

    - ASCII码中利用8个bit,从0(0000 0000)到127(0111 1111),每个二进制数均对应一个特定的字符,char 数据类型 能有效接收这128个字符,但是无论传给什么数据类型,他们最终都以二进制数保存。

    - 当输出要求为%c,编译器则认为把存储的二进制转换为对应的字符输出

    - 当输出要求为%d,编译器则认为把存储的二进制转换为十进制输出

    从补码的意义上去理解

    ∵256-128=256+(-128)的补码

    又∵256-128=128

    ∴256+(-128)的补码=128

    ∴ -128)的补码 =256-128=128

    数学上,128=1000 000 所以规定**-128**的补码为1000 0000

    (重点 圈起来)超出其范围举例:

    0b4f4c4f5b7c0586e2b3f2e1be354f23.png

    char a = 128时,赋值给a后,a代表的存储空间中存储的是1000 0000,但取出来的时候,因符号位是1,系统认为他是一个负数的补码,1000 0000其实就是-128的补码,故第一个输出的是-128

    2b479c8f56a7b7a7a3cb3ec0a33df476.png

    char a = -129时,a代表的存储空间是0111 1111,因为,-129的原码

    是1 1000 0001,反码是1 0111 1110 ,补码是1 0111 1111.系统就读低(后)8位,也就是0111 1111,认为是一个正数,而0111 1111是127的补码,故输出127.

    -------------------------------------------------------------------参考计算机组成原理一书

    本帖子中包含资源

    您需要 登录 才可以下载,没有帐号?立即注册

    展开全文
  • C语言实现原码补码输出

    万次阅读 2015-05-30 20:19:32
    今天复习了一下C中的原码补码的知识,顺便编程使用for , while, do-while,goto,recursive 实现了补码和原码的输出。 核心思想: 借助一个字符串数组,将得到的原码和补码存储到相应数组中去。在计算原码的时候...

    今天复习了一下C中的原码补码的知识,顺便编程使用for , while, do-while,goto,recursive 实现了补码和原码的输出。


    核心思想: 借助一个字符串数组,将得到的原码和补码存储到相应数组中去。在计算原码的时候,由于存在负数的补码等于原码取反+1的这么一个关系,因而只要计算一个在计算机内部存贮着的补码就可以了。而获取补码的方式很简单,只需要依次做位与操作,逐个取出即可。


    ps: 这个版本的代码 可以很好的兼容 int short long等数据类型的输出

    // ================【5种方式输出补码和原码】======================
    // @ author         :       zhyh2010
    // @ date           :       20150530
    // @ version        :       1.1
    // @ description    :       5 种方式 实现补码 和 原码的输出
    //
    
    #define DateType long
    #define BitNum 32
    
    void findNegCode_iter(DateType num, char * code, int bitNum, int cur_iter_num)
    {
        if (cur_iter_num == bitNum)
            return;
    
        code[cur_iter_num] = (num & 1 << (BitNum - 1 - cur_iter_num)) == 0 ? '0' : '1';
        findNegCode_iter(num, code, bitNum, cur_iter_num + 1);
    }
    
    void findNegCode(DateType num, char * code, int bitNum)
    {
        DateType inum = num;
    //  =============【for】============
    //  for (int i = 0; i != bitNum; i++)
    //      code[i] = (inum & 1 << (BitNum - 1 - i)) == 0 ? '0' : '1';
    
    //  =============【while】============
    //  int i = 0;
    //  while (i != bitNum)
    //      code[i++] = (inum & 1 << (BitNum - 1 - i)) == 0 ? '0' : '1';
    
    //  =============【do while】============
    //  int i = 0;
    //  do 
    //  {
    //      code[i++] = (inum & 1 << (BitNum - 1 - i)) == 0 ? '0' : '1';
    //  } while (i != bitNum);
    
    //  =============【goto】============
    //  int i = 0;
    // LOOP:
    //  code[i++] = (inum & 1 << (BitNum - 1 - i)) == 0 ? '0' : '1';
    //  if (i != bitNum)
    //      goto LOOP;
    
        //  =============【recursive】============
        findNegCode_iter(num, code, bitNum, 0);
    }
    
    void findOriCode(DateType num, char * code, int bitNum)
    {
        findNegCode(num, code, bitNum);
    
        if (num > 0)
            return;
    
        findNegCode(num * (-1), code, bitNum);
        code[0] = '1';
    }
    
    void main()
    {
        for (DateType num = -5; num != 6; num++)
        {
            char OriCode[BitNum + 1] = { 0 };
            char NegCode[BitNum + 1] = { 0 };
    
            findOriCode(num, OriCode, BitNum);
            findNegCode(num, NegCode, BitNum);
    
            printf("num = %d\n\t原码:\t%s\n\t补码:\t%s\n", num, OriCode, NegCode);
        }
    
        return;
    }
    展开全文
  • 四:二进制与补码二进制: 数码:0,1基数:2二进制数的权展开式:(101.01) = 1*2²+0*2¹+1*2⁰+0*2⁻¹+1*2⁻²十进制转化为二进制: 除以二逆向取余法十进制转化为二进制(小数):乘以二顺向取整法在汇编中,在...

    四:二进制与补码

    二进制: 数码:0,1

    基数:2

    二进制数的权展开式:

    (101.01) = 1*2²+0*2¹+1*2⁰+0*2⁻¹+1*2⁻²

    十进制转化为二进制: 除以二逆向取余法

    十进制转化为二进制(小数):乘以二顺向取整法

    在汇编中,在数字后加字母B表示二进制数,加字母O表示八进制,加字母D表示十进制,加字母H是16进制

    负整数转二进制:先求与该负数相对应的正整数的补码,然后将所有位取反,末尾+1,不够位数时,左边补1

    正数的原码、反码和补码相同,负数都不相同

    补码:

    原码 :也叫符号绝对值🐎

    最高位0表示+,1表示-,其余二进制位是该数字的绝对值的二进制位

    原🐎简单易懂

    加减运算复杂

    存在加减乘除四种运算,增加了cpu的复杂度

    0的表示不唯一

    反码:反码运算便,也没有在计算中应用

    移码移码表示数值平移n位,n称为移码量

    移码主要用于浮点数的阶码的存储

    补码:解决整数的存储,

    二进制负数求十进制:将所有位取反,末尾加1,所得数字是该负数的绝对值

    五:宏定义和枚举

    宏定义

    #define 名字 值

    注意:结尾无分号,因为不是C的语句

    名字可以是各种单词,值可以是各种东西,比如输出控制或字符

    在进行,编译之前,会先进性预处理,把这些名字全部替换为值

    如果一个宏,有其他宏,会被再次替换

    如果宏中的值超过一行,则在最后一行加上一个\

    定义宏时,也可以不写值

    预定义的宏有如下:

    __LINE__

    __FILE__

    __DATE__

    __TIME__

    __STDC__

    枚举:语法:

    enum 枚举类型的标记名{枚举成员列表};//其中的枚举成员列表是以逗号“,”相分隔,花括号内被称为枚举元素或枚举常量

    枚举常量是另外一种类型变量,枚举是一个长量整形值的列表,例如

    enum{JAN = 1, FEB, MAR, APR , MAY ,JUN, JUL, AUG, SEP,OCT,NOV,DEV};

    //在没有显示说明的情况下,enum类型中第一个枚举名的值为0,第二个为1,依次类推

    //如果只制定部分枚举名的值,那么未指定的枚举名的值将依着最后一个指定值向后递增。

    //不同枚举中的名字必须互不相同,🙆‍♂同一枚举中不同的名字可以具有相同的值

    //枚举为建立常量值与名字之间的关联提供了一种便利方式。相对于#define来说,优势在于常量值可以自动生成。

    此外:虽然可以通过声明变量的形式,但是编译器不检查的这种类型的变量中的存储的值是否是有效值。而枚举变量提供这种检查。

    展开全文
  • C语言中源码和补码详解

    千次阅读 2020-01-07 23:49:39
    1、计算机中存储的补码输出的是源码。 解释: int max = 0x7fff ffff; //+2147483647 printf("%d",max);//输出的是+2147483647,因为正数的补码就是他本身 int min = 0x8000 0000; //-2147483648 printf("%d...
  • C语言中反码和补码

    2016-10-18 23:38:00
    unsigned char a1 = 129; char a = 129; char b = 128; char c = -1; printf("\n,%d,%d,%d,%d", a, b,c,a1 ); printf("\n");... printf("\n%x, %x, %x",&a, &b,&c);...输出结果: -127, -128, -1,
  • 题目最后的答案是输出-1 在网上查了相关资料,说是关于补码与原码转换的 但是看完之后仍然觉得有疑问 疑问1:十六进制在内存中是否是转化为二进制原码之后再以补码储存的? 疑问2:后面那个x--的作用是什么...
  • 一、选择题 (每题1分,共15分) 在每小题列出的四个选项中只有一个是符合题目要求的,请在正确答案前点选,错选或未选均不得分。...补码B.反码C.原码D.ASCII 码正确答案:D3.设 x,y,z 为 int 型变量,...
  • #include #include int main(void) ...//以16进制输出.输出结果是:0XFFFFFFFD请按任意键继续. . . printf("%X",i);//输出结果是:FFFFFFFD请按任意键继续. . . system("pause"); return 0; /* 计
  • 数据在内存以补码形式存储,那为什么比如:int i=-3;输出是-3,不是-3的补码
  • c语言中printf("%x",-1);为什么会输出-1的十六进制补码???
  • 然后改为char类型,最后输出的%d是打印十进制的有符号数字,所以把缺的位置补上,再通过补码写出源码 //源码首位表示符号位,0为正数,1为负数,正数的源码,反码,补码都一样,负数的反码是源码符号位不变,剩余位...
  • //输出一个整数二进制(补码)中1的个数 int count_bit_one(unsigned int n)//形参为无符号整数,对于负数而言,其最高位不表示符号位,表示有效位,这种思想至关重要 { int count=0; while(n) { if(n%2==1) ...
  • 补码与符号位取反先来一个 C 语言的小例子:#include #include int main(void){int16_t n = -1;n &= 0x7FFF; // 按位与printf("%d", n); // 这里输出什么?return 0;}对于16位的整数 n ,按位与运行将最高位设置...
  •  数据在计算机内部是以补码的形式储存的。  引入原码、反码、补码的意义:  为了计算机电路的设计更加简单,计算机只能执行加法,如果执行减法,就等于加上一个负数。这时,反码和...
  • int count_bit_one(unsigned int num)//负数的源码和补码不相同,所以把负数的二进制补码转化成对应的无符号的源码的数。正数的源码和补码相同。 { //此方法是对一个数的二进制源码进行操作的 int count = 0; ...
  • //在C语言中没有提供二进制的输出格式符 intnum3 = 0x6c; //在数值前面加上0x就代表十六进制 printf("%dn", num3); printf("%xn", num); //%x是以十六进制的方式输出一个整数 2. 常见的进制转换 10—>2:除2取余法...
  • 进制转换及补码 位运算符  约翰·冯·诺依曼(JohnVonNouma,1903-1957),美藉匈牙利人  被称为计算机之父:2大贡献  二进制  计算机设备分类:运算器 控制器 存储器 输入设备 输出设备   什么是进制 ...
  • 计算机中的进制 #include int main(int argc, ... //C语言默认是十进制,关于进制都不区分大小写的  //以0b或0B开头是二进制数  int b = 0b1101;  printf("%d\n",b);//%d是按十进制输出  //以0开头的是八
  • int main(){ char c1,c2; c1=130; c2=131; printf("%c %c\n",c1,c2); printf("%d %d\n",c1,c2); return 0; } 输出结果是 ?? -126 -125 ...我发现数字在计算机内存中是以补码储存的...
  • 目录一、实验环境二、C语言整数简介1、类型说明符(1) signed和unsigned(2) 省略书写2、sizeof运算符-计算当前环境下各类型的字节数三、整数存储-原码,反码,补码1、原码2、反码3、补码四、总结五、文末声明 ...
  • ## 问题如下:请问在C语言中以十进制输出0xFFFFFFFF为什么结果为-1? * 查询过相关CSDN文章,都是在说0xFFFFFFFF是个补码,然后介绍补码转化的方法,最后得出结果为-1。 * 但是我的疑惑就在于为什么0xFFFFFFFF是...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 140
精华内容 56
关键字:

c语言输出补码

c语言 订阅