这个牵扯到计算机的计算原理。都知道计算机都是以二进制来存储的,所二进制的加减乘除可以看成是 异或,移位来运算得到。
package Opera;
/**
* 不用 "+ , - , * , /"进行四则运算
*
* @author Administrator
*
*/
public class FourOPera {
public static void main(String[] args) throws Exception {
System.out.println(add(5, 17));// 正负数 都适用
System.out.println(add(-5, -17));
System.out.println(by(14097, 56));
System.out.println(_by(14097, 56));
System.out.println(divide(789456, -56));
}
/**
* 1、模拟加法,先进行不进位加法 2、在进行进位计算 3、将结果相加(这里是二级制结果)<br>
*
* 对于二进制相加其实就是 异或( 1 + 1 = 0, 1 + 0 = 1, 0 + 1 = 1) --> a ^ b <br>
* eg: 5 + 17 => 101 + 10001; <br>
* a ^ b => 10100 => 4 + 16 = 20; <br>
* a & b << 1 = > 00001 << 1 => 00010 => 2<br>
* 20 + 2 = 22;<br>
*
* @param a
* @param b
* @return
*/
public static int add(int a, int b) {
int sum = 0, carry = 0;
while (b != 0) {
sum = a ^ b;
carry = (a & b) << 1;
a = sum;
b = carry;
}
return sum;
}
/**
* 计算乘法 比如 5 * 3 实际上就是 5 + 5 + 5。<br>
* 貌似就说完了。实际上不仅仅如此的。现在有一个电子器件叫做乘法器,其可以实现二进制的乘法、除法等运算。我们同样以 5 * 3<br>
* 做为例子,讲解一下乘法器计算乘法的流程。<br>
*
* 5 * 3 = 0000 0101 * 0000 0011 <br>
* 3 的第 0 位为 1 ,那么 5 左移 0 位,结果为 0000 0101 ; <br>
* 3 的第 1 位为 1 ,那么 5 左移 1 位,结果为 0000 1010 ; <br>
* 3 的其他高位都为 0 ,因此不再左移; 两次左移的结果累加,<br>
* 即 0000 0101 + 0000 1010 = 0000 1111 ,即十进制的 15 。<br>
*
* @param a
* @param b
* @return
* @throws Exception
*/
public static int by(int a, int b) {
if(a == 0 || b == 0) {
return 0;
}
boolean isAf = false;
boolean isBf = false;
if(a < 0) {
a = -a;
isAf = true;
}
if(b < 0) {
b = -b;
isBf = true;
}
int brr[] = new int[32];
int result[] = new int[32];
// 取到二进制
int i = 32;
while (i-- > 0) {
brr[31 - i] = b >> i & 1;
}
int index = 0;
for (int j = 31; j > 0; j--) {
if (brr[j] >= 1) {
result[index++] = a << (31 - j);
}
}
int r = 0;
for (int j = 0; j < 32; j++) {
r += result[j];
}
if(!isAf && !isBf || isAf && isBf) {
return r;
}else {
return -r;
}
}
/**
* 当然 乘法其实还可以看成 加法运算,所以也可以这样计算<br>
*
* 3 * 5 => 00011 * 00101<br>
* 其实也是移位
* @param a
* @param b
* @return
*/
public static int _by(int a, int b) {
int ans = 0;
int index = 0;
while(b != 0) {
if((b & 1) == 1) {
ans = add(ans , a << index);
}
index = add(index, 1);
b = b >> 1;
}
return ans;
}
/**
* 模拟除法 运算,结果保留整数位<br>
* 其实就是不断的减去除数<br>
* @param a
* @param b
* @return
*/
public static int divide(int a, int b) {
int ans = 0;
int result = 0;
if(a == 0) {
return 0;
}
if(b == 1) {
return a;
}
if(b == - 1) {
return - a;
}
boolean isAf = false;
boolean isBf = false;
if(a < 0) {
a = -a;
isAf = true;
}
if(b < 0) {
b = -b;
isBf = true;
}
while(a >= b) {
ans = add(a , - b);
a = ans;
result ++;
}
if(!isAf && !isBf || isAf && isBf) {
return result;
}else {
return - result;
}
}
}
运行结果:
22
-22
789432
789432
-14097
当然上面运算是有条件限制的,都是在int范围,且结果也是在int范围。假如加入小数运算,目前还不能满足。但是仔细一想。小时候我们学小数运算的时候。也是把小数当整数来计算,然后在把小数位加上去。归根结底其实还是四则运算原理。