原码:
原码(true form)是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位表示数值的大小。
不能直接参与运算,因为其首位表示符号位。
补码:
正整数的补码是其二进制表示,与原码相同
求负整数的补码,将其对应正数二进制表示所有位取反(包括符号位,0变1,1变0)后加1
注:
在计算机中,正数是直接用原码表示的,如单字节5,在计算机中就表示为:0000 0101。负数用补码表示,如单字节-5,在计算机中表示为1111 1011。
补码的移位:
左移,无论正数负数都在右边补0;
右移,正数在左边补0,负数在左边补1;
方法1:#include<iostream>
using namespace std;
class Solution {
public:
int NumberOf1(int n) {
if(n==0) return 0;
if(n>0)
{
int Num=0;
while(n!=0)
{
if(n%2==1) Num++;
n=n/2;
}
return Num;
}
else
{
unsigned int N;
N=(unsigned int)n;
int Num=0;
while(N!=0)
{
if(N%2==1) Num++;
N=N/2;
}
return Num;
}
}
};
int main()
{
Solution S1;
int n=0;
while(1)
{
cin>>n;
cout<<S1.NumberOf1(n);
cout<<endl;
}
}
方法2:敌动我不动
class Solution {
public:
int NumberOf1(int n) {
if(n==0) return 0;
if(n>0)
{
int Num=0;
while(n)
{
if(n&1) Num++;
n=n>>1;
}
return Num;
}
else
{
unsigned int N;
N=(unsigned int)n;
int Num=0;
while(N!=0)
{
if(N%2==1) Num++;
N=N/2;
}
return Num;
}
}
};
方法3:我动敌不动,避免负数进入死循环
class Solution {
public:
int NumberOf1(int n) {
int Num=0;
unsigned int flag=1;
while(flag)
{
if(n&flag) Num++;
flag=flag<<1;
}
return Num;
}
};
方法4:快速求解
把一个整数减去1之后再和原来的整数做位与运算,得到的结果相当于是把整数的二进制表示中的最右边一个1变成0
每次在最右的1设置一个flag的话,
当它(i)与它前一位(i-1)进行&操作时,对flag左边的1是没有影响的,每次得到的结果,就会将flag位置及右边所有的数置为0.
例如:11010&11001 ==11000(24)
那么,结束条件是什么呢?
那就是当&操作后的结果为0,循环结束。
class Solution {
public:
int NumberOf1(int n) {
int Num=0;
while(n)
{
Num++;
n=n&(n-1);
}
return Num;
}
};