位运算的操作(加减乘除、负数、乘方、1的个数)

一、位运算相关规律+口诀

c++中的位运算相关规律总结和口诀

二、加减乘除

int add(int num1, int num2){ 
	int temp;
    do {
    	temp = num1 ^ num2;//不进位相加:异或
    	num2 = (num1 & num2) << 1;//进位:位与+左移
    	num1 = temp;
    } while(num2!=0);
    return num1;
}
//num1为被减数,num2为减数
int substract(int num1, int num2){
    int subtractor = add(~num2, 1);//负数:取反加1
    int result = add(num1, subtractor);  
    return result ;
}
1、1110&1,最后1位=0,所以结果=0;被乘数1101左移1位=11010,乘数1110右移1位=0111;
2、0111&1,最后1位=1,所以结果=11010;被乘数11010左移1位=110100,乘数0111右移1位=0011;
3、0011&1,最后1位=1,所以结果=11010+110100=1001110;被乘数110100左移1位=1101000,乘数0011右移1位=0001;
4、0001&1,最后1位=1,所以结果=1001110+1101000=10110110;被乘数110100左移1位=11010000,乘数0011右移1位=0
乘数=0,循环结束。
(1) 判断乘数是否为0,为0跳转至步骤(4)
(2) 将乘数与1作与运算,确定末尾位为1还是为0,如果为1,则相加数为当前被乘数;如果为0,则相加数为0;将相加数加到最终结果中
(3) 被乘数左移一位,乘数右移一位;回到步骤(1)
(4) 确定符号位,输出结果;
//multiplicand被乘数,multiplier乘数,product乘积
int multiply(int a, int b) {  
    //将乘数和被乘数都取绝对值 
    int multiplicand = a < 0 ? add(~a, 1) : a;   
    int multiplier = b < 0 ? add(~b , 1) : b;  
     
    //计算绝对值的乘积  
    int product = 0;  
    while(multiplier > 0) {    
        if((multiplier & 0x1) > 0) {// 每次考察乘数的最后一位    
            product = add(product, multiplicand);    
        }     
        multiplicand = multiplicand << 1;// 每运算一次,被乘数要左移一位    
        multiplier = multiplier >> 1;// 每运算一次,乘数要右移一位(可对照上图理解)  
    }   
    //计算乘积的符号  
    if((a ^ b) < 0) {    
        product = add(~product, 1);  
    }   
    return product;
}

 

计算机是一个二元的世界,所有的int型数据都可以用[2^0, 21,...,231]这样一组基来表示(int型最高31位)。不难想到用除数的231,230,...,22,21,2^0倍尝试去减被除数,如果减得动,则把相应的倍数加到商中;如果减不动,则依次尝试更小的倍数。这样就可以快速逼近最终的结果。2的i次方其实就相当于左移i位,为什么从31位开始呢?因为int型数据最大值就是2^31

//dividend被除数,divisor除数,quotient商,remainder余数
int divide_v2(int a,int b) {   
    // 先取被除数和除数的绝对值    
    int dividend = a > 0 ? a : add(~a, 1);    
    int divisor = b > 0 ? a : add(~b, 1);    
    int quotient = 0;// 商    
    int remainder = 0;// 余数    
    for(int i = 31; i >= 0; i--) {
        //比较dividend是否大于divisor的(1<<i)次方,不要将dividend与(divisor<<i)比较,而是用(dividend>>i)与divisor比较,
        //效果一样,但是可以避免因(divisor<<i)操作可能导致的溢出,如果溢出则会可能dividend本身小于divisor,但是溢出导致dividend大于divisor       
        if((dividend >> i) >= divisor) {            
            quotient = add(quotient, 1 << i);            
            dividend = substract(dividend, divisor << i);        
        }    
    }    
    // 确定商的符号    
    if((a ^ b) < 0){
        // 如果除数和被除数异号,则商为负数        
        quotient = add(~quotient, 1);    
    }    
    // 确定余数符号    
    remainder = b > 0 ? dividend : add(~dividend, 1);    
    return quotient;// 返回商
}

三、判断整数number是否是2的乘方

bool isPower(int number) {
	return (number & number - 1) == 0;
}

四、判断正整数转换成二进制后的数字“1”的个数

//乘方:n&(n-1)可以把整数二进制的最右边的数由1变为0 
int bitCount1(int n) {
	int count = 0;
	while (n != 0) {
	    n = n & (n - 1);
	    count++;
	}
	return count;
}

//移位: 二进制与1进行&运算的时候,当最末位也就是最右边的一位为1的时候,结果就是1,
//判断完最后一位,然后把整数的二进制右移一位,再判断,直到整数等于 0 结束循环
int bitCount2(int n) {
	int count = 0;
	while (n > 0) {
	    if ((n & 1) == 1) count++;//如果最右边的值是1
	    n >>= 1; //向右一位
	}
	return count;
}

//可忽略。分治法,详见:https://www.jianshu.com/p/d8a0c6299dab
int bitCount3(int i) {
	i = i - ((i>>>1) & 0x55555555);
	i = (i & 0x33333333) + ((i>>>2)&0x33333333);
	i = (i+(i>>>4)) & 0x0f0f0f0f;
	i = i + (i>>>8);
	i = i + (i>>>16);
	return i & 0x3f;
}

转载:加减乘除

判断一个整数是否是2的乘方

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,在 Android Studio 中创建一个新项目,然后在布局文件中添加一个 TextView 和多个 Button,以实现计算器的界面。 接下来,在 MainActivity.java 中编写代码来实现计算器的功能。以下是一个简单的实现示例: ```java import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import java.text.DecimalFormat; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private TextView mDisplayText; private Button mButton0, mButton1, mButton2, mButton3, mButton4, mButton5, mButton6, mButton7, mButton8, mButton9; private Button mButtonPlus, mButtonMinus, mButtonMultiply, mButtonDivide, mButtonPower, mButtonSqrt, mButtonEqual, mButtonClear; private String mNumber1 = "", mNumber2 = "", mOperator = ""; private DecimalFormat mDecimalFormat; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDisplayText = findViewById(R.id.display_text); mButton0 = findViewById(R.id.button_0); mButton1 = findViewById(R.id.button_1); mButton2 = findViewById(R.id.button_2); mButton3 = findViewById(R.id.button_3); mButton4 = findViewById(R.id.button_4); mButton5 = findViewById(R.id.button_5); mButton6 = findViewById(R.id.button_6); mButton7 = findViewById(R.id.button_7); mButton8 = findViewById(R.id.button_8); mButton9 = findViewById(R.id.button_9); mButtonPlus = findViewById(R.id.button_plus); mButtonMinus = findViewById(R.id.button_minus); mButtonMultiply = findViewById(R.id.button_multiply); mButtonDivide = findViewById(R.id.button_divide); mButtonPower = findViewById(R.id.button_power); mButtonSqrt = findViewById(R.id.button_sqrt); mButtonEqual = findViewById(R.id.button_equal); mButtonClear = findViewById(R.id.button_clear); mDecimalFormat = new DecimalFormat("#.##########"); mButton0.setOnClickListener(this); mButton1.setOnClickListener(this); mButton2.setOnClickListener(this); mButton3.setOnClickListener(this); mButton4.setOnClickListener(this); mButton5.setOnClickListener(this); mButton6.setOnClickListener(this); mButton7.setOnClickListener(this); mButton8.setOnClickListener(this); mButton9.setOnClickListener(this); mButtonPlus.setOnClickListener(this); mButtonMinus.setOnClickListener(this); mButtonMultiply.setOnClickListener(this); mButtonDivide.setOnClickListener(this); mButtonPower.setOnClickListener(this); mButtonSqrt.setOnClickListener(this); mButtonEqual.setOnClickListener(this); mButtonClear.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.button_0: onNumberClicked("0"); break; case R.id.button_1: onNumberClicked("1"); break; case R.id.button_2: onNumberClicked("2"); break; case R.id.button_3: onNumberClicked("3"); break; case R.id.button_4: onNumberClicked("4"); break; case R.id.button_5: onNumberClicked("5"); break; case R.id.button_6: onNumberClicked("6"); break; case R.id.button_7: onNumberClicked("7"); break; case R.id.button_8: onNumberClicked("8"); break; case R.id.button_9: onNumberClicked("9"); break; case R.id.button_plus: onOperatorClicked("+"); break; case R.id.button_minus: onOperatorClicked("-"); break; case R.id.button_multiply: onOperatorClicked("*"); break; case R.id.button_divide: onOperatorClicked("/"); break; case R.id.button_power: onOperatorClicked("^"); break; case R.id.button_sqrt: onOperatorClicked("sqrt"); break; case R.id.button_equal: onEqualClicked(); break; case R.id.button_clear: onClearClicked(); break; } } private void onNumberClicked(String number) { if (mOperator.isEmpty()) { mNumber1 += number; mDisplayText.setText(mNumber1); } else { mNumber2 += number; mDisplayText.setText(mNumber2); } } private void onOperatorClicked(String operator) { if (!mNumber1.isEmpty() && mNumber2.isEmpty()) { mOperator = operator; mDisplayText.setText(mNumber1 + " " + operator + " "); } } private void onEqualClicked() { double result = 0.0; if (!mNumber1.isEmpty() && !mNumber2.isEmpty()) { double num1 = Double.parseDouble(mNumber1); double num2 = Double.parseDouble(mNumber2); switch (mOperator) { case "+": result = num1 + num2; break; case "-": result = num1 - num2; break; case "*": result = num1 * num2; break; case "/": result = num1 / num2; break; case "^": result = Math.pow(num1, num2); break; } mDisplayText.setText(mDecimalFormat.format(result)); mNumber1 = mDecimalFormat.format(result); mNumber2 = ""; mOperator = ""; } else if (!mNumber1.isEmpty() && mNumber2.isEmpty() && mOperator.equals("sqrt")) { double num1 = Double.parseDouble(mNumber1); result = Math.sqrt(num1); mDisplayText.setText(mDecimalFormat.format(result)); mNumber1 = mDecimalFormat.format(result); mNumber2 = ""; mOperator = ""; } } private void onClearClicked() { mNumber1 = ""; mNumber2 = ""; mOperator = ""; mDisplayText.setText(""); } } ``` 在这个示例代码中,我们实现了加、减、乘、除、乘方、开方等基本算术运算,并且使用 DecimalFormat 对结果进行格式化。当用户点击数字按钮时,我们将数字添加到当前操作数中;当用户点击操作符按钮时,我们将当前操作数视为第一个操作数,并将操作符保存;当用户点击等号按钮时,我们计算结果并在 TextView 中显示;当用户点击清除按钮时,我们将所有操作数和操作符都重置为初始状态。 最后,运行应用程序并测试计算器的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值