-
2021-02-12 22:57:33
二进制整数的Java实现
任意两个二进制数(不论在什么位置)相加,只可能出现4种情况。它们是:
0+0=0
1+0=0+1=1
1+1=10=0+向高一位的进位1
1+1+1=11=1+向高一位的进位1
//整数二进制相加
public static String add(String b1, String b2) {
int len1 = b1.length();
int len2 = b2.length();
String s1 = b1;
String s2 = b2;
StringBuffer sb1 = new StringBuffer();
//先将位数较少的二进制高位补零
if(len1 > len2) {
for(int i = 0; i < (len1 - len2); i++) {
sb1.append(0);
}
sb1.append(b2);
s1 = b1;
s2 = sb1.toString();
} else if(len1 < len2) {
for(int j = 0; j < (len2 - len1); j++) {
sb1.append(0);
}
sb1.append(b1);
s1 = sb1.toString();
s2 = b2;
}
<更多相关内容 -
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,加法结果的结果,高位会被省去,这也是为什么会计算出负数的原因
-
java二进制运算器(加、见、乘、除)
2010-06-20 16:26:39java二进制运算器(加、见、乘、除)********** -
二进制的加减乘除实现
2021-08-27 22:17:41当二进制加法没有进位时,两个数的加法其实就是按位异或,例如3 + 4 = 7,011 + 100 = 111,这个结果就是按位异或得到的结果,但是我们的加法肯定是存在进位的,那我们进位怎么表示呢,我们想一下,我同样使用异或...1. 加法
当二进制加法没有进位时,两个数的加法其实就是按位异或,例如3 + 4 = 7,011 + 100 = 111,这个结果就是按位异或得到的结果,但是我们的加法肯定是存在进位的,那我们进位怎么表示呢,我们想一下,我同样使用异或运算,当只考虑一位的时候(a表示其中一个数的第i位,b表示另外一个数的第i位),只有两个1才会有进位,这就和与运算是一样的,但是进位肯定是要往前移位的,所以进位可以表示为 a & b << 1
递归写法
public int sum(int a, int b) { // 如果b为0,则表示没有进位了,那么a就是结果 if (b == 0) { return a; } return sum(a ^ b, (a & b) << 1); }
非递归写法
public int sum(int a, int b) { while (b != 0) { // 保留a的值 int t = a; a = a ^ b; b = (t & b) << 1; } return a; }
2. 减法
减法可以转换为加法,就不赘述了,例如a - b = a + (-b)
3. 乘法
关于二进制的乘法,例如 110 * 1010101,a * b 我们可以以其中a为基准,判断a的最低位是否为1,如果最低位是1,则结果加上b,然后a右移一位,b左移一位,直到a等于0,最后的结果就是结果 + b,我们判断最低位是否为1是因为我们右移的时候会丢失这个1,其实就是一个数除2,另外一个数乘2,对于结果是没有影响的,例如 6 * 43 = 3 * 86 = 86 + (1 * 172) = 86 + 172,就是这样的一个过程
代码实现public int mul(int a, int b) { int res = 0; while (a != 0) { if ((a & 1) == 1) { res += b; } a >>= 1; b <<= 1; } return res; }
4. 除法(整数除法)
关于二级制的除法,其实和乘法是相反的,分为以下几个步骤,a / b,默认 b < a
- 将 b 的位数通过移位与 a 对齐,记为b1
- 如果 a >= b1,则 a = a - b1,res += 2 的(b的位数- b1的位数)次方,然后 b1 右移一位
- 如果 b1 大于等于 b,继续步骤 2
- 最后得到结果res,a 就是 a / b 的余数
整体过程描述:10 / 3
- a = 10 b = 3 res = 0 b1 = 12
- a = 10 b = 3 res = 0 b1 = 6
- a = a - b1 = 4 b = 3 res += 2 ^ (3 - 2) = 2 b1 = 3
- a = a - b1 = 1 b = 3 res += 2 ^ (2 - 2) = 2 + 1 = 3 b1 = 1
即最后的结果 res = 3,余数 a = 1
代码实现// 默认a b和运算中的结果都在int范围内 // 默认都是正数,如果出现负数,则符号统一处理 public int div(int a, int b) { // 如果 a < b,直接返回0 if (a < b) { return 0; } int count = 0; // 记录b移位的次数,即 b 和 b1 相差位数(二进制) int b1 = b; int res = 0; // 记录结果 // 模拟移位 while (b1 < a) { ++count; b1 <<= 1; } while (b1 >= b) { if (a >= b1) { a -= b1; res += (1 << count); } b1 >>= 1; --count; } return res; }
PS: 这个除法并不适用于所有的 int 整数的除法,当出现一些特殊值时,可能导致溢出,例如Integer.MIN_VALUE等
-
二进制实现加法(java)
2021-12-23 10:56:03二进制位运算实现加法(Java)常用的位运算符:
与(&) 同1出1,有0出0
或(|)有1出1,全0出0
异或(^)相同出0,不同出1
非(~)又叫取反
左移 << (即乘2,最右边加个0)
右移 >> (即除2删掉最右边一位)
做法:
求加法主要用到 异或 (^) 和 与(&) 这两个运算符
异或 用来求不需要进位的位相加。(都是0的时候是0,单独一个1的时候就是本位的值,都是1要进位)
与 用来求进位的和(因为相同出1,相同的时候肯定是需要进位的),因为是进位,所以需要左移一位,要不然就错了(如 101 & 101 结果是101,我们要的是1010,因为是进位)
本位跟进位都求好,在用它重复上面的做法即可,把它重新当做个新加法算。(最后进位为0的时候就结束了)
代码如下:
public int add(int a, int b) { while(b != 0){ int c = (a & b) << 1; a = a ^ b; b = c; } return a; }
注:此处代码是32位以内的运算,因为是int类型(若要更多位数,用long类型需要)
-
java实现字符串二进制的加法
2021-11-18 19:07:34* @param a 第一个要加的二进制字符串 * @param b 第二个要加的二进制字符串 * @return */ // String:不可变字符序列(操作少量的数据用 String) // StringBuilder:可变字符序列、效率高、线程不安全(单... -
根据java16进制数与2进制数互相转化方法.pdf
2020-08-19 00:30:28//十六进制数转二进制数 import java.util.Scanner; public class H_to_B { static void HtoB_fun(String n){ char[] ch=n.toCharArray; char str; String s=; int p=0; for(int i=0;i;i++){ str=ch[i]; if(str>='0 -
java实现二进制的加法
2021-02-13 01:50:14总结:讲解了二进制的按位异域、按位与、左移的运算规则。并通过次3种算法得到2个数相加的结果。二进制应该还有其他算法,由于知识浅薄就不知道了。代码:public static void main(String[] args){int a=11,b=9;//... -
二进制加减溢出问题详解,byte类型加减溢出详解。
2020-07-16 20:02:45剩余7位表示数值,根据二进制的计算方法,byte8位一共可以表示-128~127。 为什么正数只能表示到127,而负数可以表示到-128呢? 这涉及到了0的问题 1000 0000 按照之前的规定来看,首位1代表符号位,说明是负数,后7... -
二进制补码 加 减 取模 java代码实现
2020-01-03 20:38:37####实现二进制补码的加法 (全加法实现) 首先声明两个int类型的变量 CF 和OF,用来模拟加法过程中的进位和溢出 对于加法结果的每一位,都是由CF、oprend1、oprend2三位异或产生的结果(这三个数里面有奇数个1,... -
java二进制运算基础知识点详解
2021-03-09 05:39:59一、二进制位运算1. 按位与(&)位运算实质是将参与运算的数字转换为二进制,而后逐位对应进行运算。按位与运算为:两位全为1,结果为1,即1&1=1,1&0=0,0&1=0,0&0=0。例如51 & 5 -> ... -
二进制的加减法_二进制加减法
2020-07-25 16:25:50二进制的加减法 1)二进制加法 (1) Binary Addition) Since binary numbers consist of only two digits 0 and 1, so their addition is different from decimal addition. Addition of binary numbers can be done ... -
【java解惑】十六进制加法问题
2021-02-13 02:01:23而十六进制、八进制、二进制在计算机中是用补码表示的。补码的优势在于:使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补码表示的数相加时,如果最高位(符号位)有进位,则... -
Java中的二进制及基本的位运算
2021-03-04 01:17:07Java中的二进制及基本的位运算二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”,由18世纪德国数理哲学大师莱布尼兹... -
java 二进制与负数互相转化
2019-12-07 11:59:011、所谓原码就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。 2、反码表示法规定:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。 原码10010= ... -
java二进制操作计算的总结
2019-03-17 07:52:26一直以来对二进制的操作计算不太清楚,这次找了一些资料完整地进行了一些总结。 一、进制类别和关系: 二进制,十进制,十六进制的区别和进制之间的相互转换方法(概念性的东西,可以百度)。 n位的二进制能够表示... -
Java二进制整数与负数的取反
2021-07-05 21:02:40此时的二进制数为补码,因为负数的补码是反码加1 先减一变为反码 1111 0101 反码再取反变为原码 1000 1010 (-10) 所以9的按位取反结果为-10 负数 负数的反码是符号位不变,其余位取反。 负数的补码是反码加1。 ... -
Java中的二进制及位运算详解
2021-04-17 09:01:511.表示方法:在Java语言中,二进制数使用补码表示,最高位为符号位,正数的符号位为0,负数为1。补码的表示需要满足如下要求。(1)正数的最高位为0,其余各位代表数值本身(二进制数)。(2)对于负数,通过对该数绝对值... -
详谈Java中的二进制及基本的位运算
2021-02-26 10:41:52二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”,...那么Java中的二进制又是怎么样的呢?让我们一起来揭开它神秘的面... -
简单计算二进制的加减法
2021-10-22 09:29:06二进制就是计算机技术中广泛采用的一种数制,由(0,1)组成。你可以广泛的认为,每一个 0,1 都(存储在)对应着一个比特位(bit),而由这些由例如:01001011就是二进制。(计算机硬件通电的时,会产生电信号,而用... -
Java位运算符及二进制常识
2021-03-08 08:22:46一、位运算 二、位移运算 三、二进制数以Java中最常使用的int类型为例(32位)。 ㈠ 符号位二进制数最左端的数字为符号位:0代表正,1代表负。㈡ 最大与最小⑴ 1是最小的正整数,符号位为0,最后一位为1,其它全部为0... -
java 二进制以及二进制运算
2019-01-09 23:02:50虽然现在很少用到二进制,可是一些源码中会经常遇到,比如: //HashMap中的hash方法: static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>&... -
java二进制正数和负数取反
2019-05-16 10:22:49“反码”,“取反”,“按位取反(~)”,这3个概念是不一样的。 取反:0变1,1变0 反码:正数的反码是其本身,对于负数其符号位...要弄懂这个运算符的计算方法,首先必须明白二进制数在内存中的存放形式,二进制数... -
java 16进制求和示例
2021-04-12 17:13:41java 16进制求和,也就是16进制字节求二进制和,自己写的逻辑有点问题,不能满足需求,故从网上搜了下,满足了需求,代码如下publicclassJinzhi16Util{publicStringmakeChecksum(Stringhexdata){if(hexdata==null||... -
Java中关于二进制以及位运算的详解
2021-03-14 12:22:55Java中的二进制及基本的位运算二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”,由18世纪德国数理哲学大师莱布尼兹... -
Java二进制补码示例
2019-05-09 21:45:44二进制表示负数的问题 我们知道十进制数1的二进制码用int型表示就是0000 0000 0000 0000 0000 0000 0000 0001 二进制码实际上并不能表示负数, 因为二进制数最小就是0000 0000 0000 0000 0000 0000 0000 0000 , ...