天天看點

Hz的進制

Problem  Description:

Hz遇到一個數學問題,想請教聰明的你:給定一個有符号整數類型的數,Hz想知道該數

二進制表示中1的個數。其中負數用補碼表示。

Input:

測試樣例輸入包含一個有符号整數類型的整數n,注意可以是負數。

Output:

該數二進制表示中1的個數。其中負數用補碼表示。

Sample  Input:

1

-5

Sample  Output:

1

31

Prompt:

int占用4位元組,32比特(即32位),資料範圍為-2147483648~2147483647[-2^31~2^31-1] 

負整數的補碼求法:将其對應正數二進制表示所有位取反(包括符号位,0變1,1變0)後加1 

如 -5 其二進制補碼1的個數為31 

-5對應正數5(00000000000000000000000000000101) 

→所有位取反(11111111111111111111111111111010) 

→加1    (11111111111111111111111111111011) 

思路:這道題首先要知道十進制數轉化為二進制數的方法,然後要分正數和負數2種情況,正數比較簡單,就不說了,主要看負數的情況。負數的話,先把其對應的正數的二進制求出來,然後逐位取反,最後再将末尾數+1,其實這跟我們計算補碼的步驟一樣,隻不過現在要用計算機語言計算補碼,下面我們就看一下具體操作。

My  DaiMa:

#include<stdio.h>

#include<iostream>

#include<math.h>

using

namespace

std;

int

main()

{

int

n,i,j,s,a[35];

while

(~

scanf

(

"%d"

,&n))

{

s=0;

if

(n>=0) //這是正數的情況

{

while

(n)

{

if

(n%2==1)

s++;

n/=2;

}

}

else

//負數的case

{

i=0;

n=

fabs

(n);//首先求對應正數的二進制

while

(n)

{

a[i]=n%2;

n/=2;

i++;

}

s=32-i;

for

(j=0;j<i;j++)//接下來就開始逐位取反

{

if

(a[j]==1)//1要變成0

a[j]=0;

else //0要變成1

a[j]=1;

}

a[0]=a[0]+1;//最後一步末尾加1,最後一步時最關鍵的一步,成功與否就看它的了

for

(j=0;j<i;j++)

{

a[j+1]=a[j+1]+a[j]/2;//主要原理是逢2進1;

a[j]=a[j]%2;

}

for

(j=0;j<i;j++)

{

if

(a[j]==1)

s++;

}

}

printf

(

"%d\n"

,s);

}

return

0;

}

繼續閱讀