精华内容
下载资源
问答
  • Java二进制加减乘除

    千次阅读 2018-02-23 13:00:39
    引子 某天研究 fail-fast机制的时候,去看了看hashCode的实现... + s[n-1]于是很不解,这个公式很明显会溢出(超过2^32),尝试了几次发现系统会输出hashCode为负数的值,就默默地去回顾一下二进制加减乘除准备工...

        引子

        某天研究 fail-fast机制的时候,去看了看hashCode的实现方式,然后发现每个对象的实现都不一样;于是研究一个String的;于是看到公式:

    s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

    于是很不解,这个公式很明显会溢出(超过2^32),尝试了几次发现系统会输出hashCode为负数的值,就默默地去回顾一下二进制的加减乘除


    准备工作:

    -2 = 0xfffffffe
    -1 = 0xffffffff
    0 = 0x0
    1 = 0x1
    2 = 0x2
    max = 0x7fffffff = 2147483647
    min = 0x80000000 = -2147483648
    正数与二进制的相互转换,就是简单的二进制与十进制的相互转换
    负数与二进制的相互转换:
    1)二进制 -> 负数 :0x80000000  取反  0x7fffffff(2147483647)  忽略符号加一 (2147483648)  结果(-2147483648)
    2)负数 -> 二进制 :-2147483648 忽略符号减一(-2147483647[0x7fffffff])   取反(0x80000000) 结果(0x80000000)
    PS:以上就是专业术语"补码"的含义,而补码存在的意义在于:让所有的加法能够使用同一种电路完成


    接下来就是四则运算:加减乘除
    1,加法[全加器]
    案例一:
    3 + 5 = 8
    ==>
      0 0 1 1  -> 3
    + 0 1 0 1  -> 5
    ----------
    = 1 0 0 0  -> 8
    因此可以看出,二进制之间的加法就是,和小学学的十进制的"尾数相加,然后进位

    案例二:
    1 + -1(0x7fffffff) = 0
    ==>
     ?_ 0 0 ... 1  -> 1
    +?_ 1 1 ... 1  -> -1
    --------------
    =1_ 0 0 ... 0  -> 0
    因此可以看出,二进制之间的加法,最高位表示的不是具体的数值,进位之后应该被舍去

    2,减法[全加器]
    减法可以实现的方案:1)类似十进制的减法直接去位 2)减法就是另类的加法
    而计算机采用的是,方法2,原因:直接可以使用全加器

    例如:a - b = a + (-b)
    而通过之前的准备可以看出:二进制中,b的负数就是b的补码
    因此,0xa - 0xb = 0xa + 0xb(补码[取反,忽略符号加一])

    3,乘法[乘法器,芯片]
    乘法可以实现方案:1)类似十进制的乘法 2)多个加法
    而计算机采用的是,方法1,原因:多个加法的算法复杂度成二次方增长

    案例一:
    3 * 5 = 15
    ==>
    0 0 1 1 -> 3
    * 0 1 0 1 -> 5
    -------------
    0 1 0 1 -> 5
    + 0 1 0 1 -> 10
    -------------
    1 1 1 1 -> 15
    PS:
    1)如果有符号,符号位另算,即:同号得正,不同号得负原则
    2)如果有位数移除,则高位直接舍去,然后得出剩下的二进制对应的值

    4,除法[芯片]
    除法可以实现方案:1)类似十进制的除法 2)多个减法,直到负数
    而计算机采用的是,方法1,原因:多个减法的算法复杂的成二次方增长
    14 / 3 = 4 余 2
    14(1110[被除数])、3(11[除数])、4([结果])、2([余数])
    ==>
    1 0 0 --> 结果[4]
    -----------
    1 1 / 1 1 1 0
    ---------------
    1 1
    ---------------
    0 1
    ---------------
    1 0
    ---------------
    1 0 --> 余数[2]
    PS:
    1)如果有符号,符号位另算,即:同号得正,不同号得负原则

    回顾之前的问题,公式溢出问题:

    s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

    就很容易解释了,

    1,31^(n-1)的结果,高位会被省去

    2,加法结果的结果,高位会被省去,这也是为什么会计算出负数的原因




    展开全文
  • 思路:若直接算二进制之间的运算,很难,所以可先将输入的二进制转换为十进制,经过十进制的加减乘除后,得到十进制结果,最后将此结果转换为二进制输出。所以需构造两个函数:dou_ten()二进制转十进制函数,ten_dou...

    以二进制的方式输入两个正整数(即0和1组成的字符串),然后输入到一个4则运算(+,-,*,/),按short型计算这两个数的运算结果,并将结果按二进制输出(高位零可不输出)

    思路:若直接算二进制之间的运算,很难,所以可先将输入的二进制转换为十进制,经过十进制的加减乘除后,得到十进制结果,最后将此结果转换为二进制输出。所以需构造两个函数:dou_ten()二进制转十进制函数,ten_dou()十进制转二进制函数;
    代码:

    #include <iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    using namespace std;
    int dou_ten(char ch[],int len){
        short x=0;
        for(int i=len-1;i>=0;i--){
            x=x+(ch[i]-'0')*pow(2,len-1-i);
        }
        return x;
    }
    
    void ten_dou(short x){
        short a[101];
        int i=0;
        while(x>0){
            a[i]=x%2;
            x=x/2;
            i++;
        }
        for(int j=i-1;j>=0;j--){
            cout<<a[j];
        }
        cout<<endl;
    }
    int main()
    {
        char ch1[20],ch2[20];
        char fu;
        short x;
        while(cin>>ch1>>ch2){
            int len1=strlen(ch1),len2=strlen(ch2);
            cin>>fu;
    
            short x1=dou_ten(ch1,len1),x2=dou_ten(ch2,len2);
    
            if(fu=='+'){
                x=x1+x2;
            }
            if(fu=='-'){
                x=x1-x2;
            }
            if(fu=='*'){
                x=x1*x2;
            }
            if(fu=='/'){
                x=x1/x2;
            }
            //cout<<x<<endl;
    
            ten_dou(x);
        }
        return 0;
    }
    
    

    结果:
    二进制数的加减乘数

    展开全文
  • 首先介绍计算机的二进制二进制常用的有原码,反码和补码,他们都是由最左边的一个符号位和右边的数值位构成。在计算机中为了更低成本的计算,数据都是用补码来存储和运算的。 原码 最高位表示符号位(0代表...

     

    首先介绍计算机的二进制码

    二进制常用的有原码,反码和补码,他们都是由最左边的一个符号位和右边的数值位构成。在计算机中为了更低成本的计算,数据都是用补码来存储和运算的。

    原码

    最高位表示符号位(0代表正数,1代表负数)。剩下的位数,是这个数的绝对值的二进制。

    比如 一个int变量大小为4字节,在32位的编译器中的二进制表示就是00000000 00000000 00000000 00000000
    那么10 的原码就是00000000 00000000 00000000 00001010
    −10的原码就是 10000000 00000000 00000000 00001010

    反码

    正数的反码和其原码是一样的
    负数的反码就是在其原码的基础上 符号位不变 其他位取反。

    10的反码就是00000000 00000000 00000000 00001010 和原码一样
    −10的反码就是11111111 11111111 11111111 11110101

    补码

    正数的补码就是其原码
    负数的补码就是在其反码的基础上+1

    10的补码就是00000000 00000000 00000000 00001010
    −10的补码就是 11111111 11111111 11111111 11111011

    总结一下

    计算机系统中,数值一律用补码来表示:因为补码可以使符号位和数值位统一处理,同时可以使减法按照加法来处理。
    二进制编码:数值编码分为原码,反码,补码,符号位均为0正1负。

    原码 -> 补码: 数值位取反加1

    补码 -> 原码: 对该补码的数值位继续 取反加1

    补码 的绝对值(称为真值):正数的真值就是本身,负数的真值是各位(包括符号位)取反加1(即变成原码并把符号位取反).

    介绍基本的位操作

    ^:按位异或;&:按位与; | :按位或
    b -> -b : 各位(包括符号位)取反加1

    用位操作实现加法运算

    我们先不考虑进位,在1位数的加法上,如下
    1. 1+1=0
    2. 1+0=1
    3. 0+1=1
    4. 0+0=0
    很明显上面几个表达式我们可以用异或进行统一
    1. 1^1=0
    2. 1^0=1
    3. 0^1=1
    4. 0^0=0
    这样我们就完成了最基础的一位数的加法,但是怎么计算二位以上的加法呢?我们发现现在方法的问题在于不能够获取进位,于是我们通过观察一位数的加法的式子,发现只有两个数位都是1的时候才会有进位,其他都不进位,这不是和&很像吗? 我们通过把+换成&得到下式
    1. 1&1=0 不进位
    2. 1&0=1 不进位
    3. 0&1=1 不进位
    4. 0&0=0 进位
    那么我们把所有位进行&操作,然后<<左移一位,不就可以当作加数当前的进位吗?
    到这里我们就完整解决了二进制相加问题中,对应位的相加和进位的问题
    1. x^y 加法
    2. (x&y)<<1 进位操作
    那么总结一下:

    定理1:设ab为两个二进制数,则a+b=a^b+(a&b)<<1
    证明:

    a^b是不考虑进位时加法结果。当二进制位同时为1时,才有进位,因此 (a&b)<<1是进位产生的值,称为进位补偿。将两者相加便是完整加法结果。

    定理2:使用定理1可以实现只用位运算进行加法运算。
    证明:

    利用定理1中的等式不停对自身进行迭代。每迭代一次,进位补偿右边就多一位0,因此最多需要加数二进制位长度次迭代,进位补偿就变为0,这时运算结束。

    那么我们可以根据上面的定理得到实际的C++代码如下

    int add(int a, int b){
        int re = a;
        while(b){
            int tmp = a;
            a = a^b;
            b = (tmp&b)<<1;
            re = a;
        }
        return re;
    }

    用位操作实现减法

    减法和加法原理相同,减去一个数相当于加上这个数的相反数,所以完全可以利用加法操作,唯一需要做的就是求出被减数的相反数。
    求相反数的方法:每一位取反,末位加一。
    代码如下:

    int subtraction(int a, int b)
    {
        b = add(~b,1); // 求b的相反数
        return add(a, b);
    }

    用位操作实现乘法

    二进制的乘法同十进制的乘法并无什么不一样,对于a∗b每次只需要将a左移对应的位,然后同上一次的结果相加即可
    当b的对应位为1的时候,对a左移一位相加即可
    当b的对应位位0的时候,对a左移一位,但是不相加
    注意到我们上面的操作都是不包括符号位的,因此我们单独考虑符号位。
    代码如下

    int getSign(int n)
    {
        unsigned count = 0;
        //计算n的位数
        do{
            ++count;
        }while(n >> count)
        //得到n的最左边的位
        return n >> (count-1);
    }
    
    int mul(int a, int b){
        bool isNegative = false;
        if(getSign(a) ^ getSigned(b))
            isNegative = true;
        if(a < 0) a = add(~a,1);//求出a的绝对值
        if(b < 0) b = add(~b,1);//求出b的绝对值
        int res = 0;
        while(b){               //当b不为0,继续循环
            if(b & 1)           //当b当前位为1 才需要加a
                res = add(res,a);
            a = a << 1;
            b = b >> 1;
        }
        if(isNegative)
            add(~res,1);
        return res;
    }

    二进制除法

    同乘法一样,除法一样可以用减法来代替,当a≥b才可以上商,在每次上一个商(也就是商值加1)之后,a=a−b
    代码如下

    int divide(int a, int b){
        if(!b)
            throw std::runtime_error("Divided can't be zero...");
        bool isNegative = false;
        bool isNegtive = false;
        if(getSign(a) ^ getSign(b))
            isNegtive = true;
        if(a < 0) a = add(~a,1);//求出a的绝对值
        if(b < 0) b = add(~b,1);//求出b的绝对值
        int res = 0;
        while(a >= b){
            res = add(res,1);
            a = subtraction(a,b);
        }
        if(isNegative)
            add(~res,1);
        return res;
    }


    ---------------------
    作者:harry_128
    来源:CSDN
    原文:https://blog.csdn.net/harry_128/article/details/80150502
    版权声明:本文为作者原创文章,转载请附上博文链接!
    内容解析By:CSDN,CNBLOG博客文章一键转载插件

    展开全文
  • 二进制加减乘除运算

    万次阅读 多人点赞 2019-03-09 11:40:48
    加减 二进制 十进制 0000 =0 0001 =1 0010 =2 0011 =3 0100 =4 0101 =5 0110 =6 0111 =7 二进制的运算算术运算二进制的加法: 0+0=0, 0+1=1 , 1+0=1, 1+1=10(向高位进位); 列如 3+1=...

    加减

    二进制 十进制
    0000 =0
    0001 =1
    0010 =2
    0011 =3
    0100 =4
    0101 =5
    0110 =6
    0111 =7

    二进制的运算算术运算二进制的加法:
    0+0=0,
    0+1=1 ,
    1+0=1,
    1+1=10(向高位进位);

    列如
    3+1=0011+0001=0100
    5+2=0101+0010=0111

    二进制的减法:
    0-0=0,
    0-1=1(向高位借位)
    1-0=1,
    1-1=0 (模二加运算或异或运算) ;
    例如
    3-1=0011-0001=0010
    5-2=0101-0010=0011

    乘除

    二进制乘除运算
    左移 -----除以2
    右移 -----乘以2
    例如:
    0110=6
    左移----0011=3
    右移------1100=12
    0010=2
    左移----0001=1
    右移----0100=4

    最后:二进制最大数,最小数

    正值的最大表示为0111 1111,= 127]
    负值的最小表示为1000 0000,即-128。

    展开全文
  • 按位与,按位或,二进制加减
  • 二进制怎么相加

    千次阅读 2018-09-28 15:02:59
    1.二进制加法运算法则: 0+0=0,0+1=1,1+0=1,1+1=10 ,也就是当两个相加的二进制位仅一位为1时,相加的结果为1;如果两个二进制位全是0,相加的结果仍为0;而如果两个相加的二进制位均为1,则结果为10(相当于十...
  • 十六进制之间加减

    2019-08-25 10:18:48
    64位有符号整数a 0x7FFFFFFFFFFFFFFF 和 b0x8000000000000000相加,之后的10进制数?... 16个F就是64个1,由于二进制有符号数都是用最高位作为符号位,计算机作为存储负数用的是补码方式,其计算方式...
  • 二进制加减乘除

    万次阅读 2011-08-25 10:38:49
    最重要的,理解十进制的借位和进位.十进制中,由于一个循环是10,所以借1位,就相当于从高位借过来10,也就是常说的借1当10,同时,高位需要减去10(外在体现上是减去1,因为高位已经在高位了).反过来,进1,就等于高位加上10,...
  • 便于加减运算和计数编码 二进制和十进制可以并易于互相转换 便于逻辑判断,1和0对应是否,真假等 二进制具有抗干扰能力强,可靠性高等特点 二进制和十进制的互相转换 二进制转十进制时,每个数乘以2的n-1次方,为...
  • 负数的二进制和十进制之间的转换

    万次阅读 2016-03-07 22:05:14
    负数的二进制和十进制之间的转换: 1. 十进制负数转换为二进制的方法为: 1、将十进制转换为二进制数。 2、对该二进制数求反。 3、再将该二进制数加1. 总之就是将十进制数转换为二进制数求补码即为结果。比如...
  • 十进制与二进制之间转换详解

    千次阅读 2019-04-13 11:35:30
    (一)十进制转二进制 (二)十进制转八进制 (一) 十进制转二进制 【基本原理】:除基数倒取余数法。 即:十进制转二进制,基数就是2,用2整除一个十进制整数,可以得到一个商和余数;再用2去除商,又会得到一...
  • java十进制与二进制之间的转换

    千次阅读 2018-04-24 21:42:30
    1.正十进制转换成二进制除2取余法:让十进制整数不断除以2,并记录余数,直至商为0,把余数倒序排列得到的即为相应的二进制数例如十进制数11最终的结果为10112.正二进制转换为十进制计算机存储数据时按字节存储,一个字节...
  • 一,二进制与十进制之间的转换(以下引自百度经验) 1、正整数转换成二进制:除二取余,然后倒序排列,高位补0。如图42转换成二进制为101010,高位补0:00101010. 2、负整数转换成二进制:先是将对应的正整数转换...
  • 所以,导师命令,要用二进制表示,每八位一组,进行加减乘除,八位和八位之间考虑进位。 如果有哪位大神能直接解决这个问题更好了。如果无法,解决两个16位的二进制数(即两个字节)的四则运算也可以。让我好有...
  • 二进制整数的,运算

    千次阅读 2015-08-14 14:59:16
    二进制整数的,运算   前言 在平时的编程中,当进行整数运算时,经常会遇到一些奇怪的结果,比如两个正数相加出现了负数,两个负数相加出现了正数,这些都是因为数值表示的有限性导致的.来看一个案例:  int a = ...
  • 二进制如何转十进制,十进制如何转二进制

    万次阅读 多人点赞 2018-04-06 17:57:29
    学计算机的朋友刚开始学习时都要接触进制之间的转换,二进制、十进制、八进制、十六进制等,这个是很枯燥的,转来转去就转蒙圈了,别蒙别蒙,今天咱们一个一个搞定,看看二进制和十进制之间如何相互转换的。 转成...
  • 二进制加减法计算法则

    千次阅读 2020-02-12 14:24:09
    一、二进制加法(逢2进1) 举例:100111+11010=100001 1 0 0 1 1 1 1 1 0 1 0 —————— 1 0 0 0 0 1 十进制加法是逢十进一,二进制加法是逢二进一。 最低位:10得1。 倒数第2位:11得2,同时进1。 倒数第3位...
  • 二进制加,减法,23个位运算技巧

    千次阅读 2019-04-06 20:36:22
    二进制加,减法 二进制最高位为1时表示负数,为0时表示正数。 **原码:**一个正数,转换为二进制位就是这个正数的原码。负数的绝对值转换成二进制位然后在高位补1就是这个负数的原码。 举例说明:  int类型的 3 的...
  • 二进制

    2017-11-14 09:58:00
    二进制 编辑 本词条由“科普中国”百科科学词条编写与应用工作项目审核 。 二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则...
  • 二进制基础

    2016-03-09 21:14:49
    进制进制是一种计数方式。最常用的就是十进制,包含0~9数字组成,满10进位。...进制之间的转换十进制–>二进制:短除2,直到商为0,从下往上取余数。 二进制–>十进制:2的(1的所在位-1)次方求和。二进制的位运算 与
  • 异步二进制计数器是计数器中最基本最简单的电路,它一般由接成计数型的触发器连接而成,计数脉冲到最低位触发器的CP端,低位触发器的输出Q作为相邻高位触发器的时钟脉冲。1.异步二进制加法计数器必须满足二进制...
  • 3、熟练掌握二进制与十进制之间的转换方法。【课时安排】 1课时。【教学重点与难点】1、难点:位权表示法 十进制转化为二进制2、重点:二、十进制间相互转换【教学过程】 (以下教师的语言、活动简称“师”,学生的...
  • 高中信息技术_二进制十进制转换教案二进制十进制转换教案【教学目的与要求】 1、熟悉数制的概念;2、掌握位权表示法; 3、熟练掌握各数制之间的转换方法。【课时安排】 1课时。【教学重点与难点】1、难点:位权表示...
  • 进制之间的转换

    2021-07-17 11:26:42
    文章目录一、进制的概念二、进制间的转换1、二进制与十进制的转换二进制转换为十进制十进制转换为二进制2、二进制与十六进制的转换二进制转换为十六进制十六进制转换为二进制3、十进制与十六进制的转换十进制转换为...
  • 将1转换成二进制数据为 0000 0000 0000 0000 0000 0000 0000 0001 学过计算机的,都知道最高位代表符号位,0为正,1为负,所以得到的二进制为 1000 0000 0000 0000 0000 0000 0000 0001 但计算机还会进行反码和...
  • 二进制、八进制、十进制、十六进制关系及转换

    万次阅读 多人点赞 2019-02-21 21:20:22
    二进制,八进制,十进制,十六进制之间的关系是什么?浮点数是什么回事? 本文内容参考自王达老师的《深入理解计算机网络》一书&amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;中国水利水电出版社&amp;amp;amp;amp...
  • 二进制学习01进制一、二进制简介1)什么是二进制?2)二进制的简写形式二、进制运算1)八进制运算表(1) 加法运算表(2)乘法运算表(3)八进制简单运算题三、数据宽度1)什么是数据宽度2)计算机中常用的基本数据宽度四、无...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 59,814
精华内容 23,925
关键字:

二进制之间的加减