負進位制轉換
題目描述
以前我們做的進位制轉換大家都忽略了一點,就是進位制一定是正整數;今天這道進位制轉換就坑爹的選擇了,額,負整數來做進位制。
輸入
輸入由若干行組成,每行有兩個整數n(-32765<=n<=32767)和R(-16<=R<=-2)。輸入的最後一行只有一個‘#’號,表示輸入結束。
輸出
對於每個輸入行,輸出n的R進位制形式。出現的字母請用大寫字母表示!
樣例輸入
30000 -2
-20000 -2
28800 -16
-25000 -16
#
樣例輸出
11011010101110000
1111011000100000
19180
7FB8
提示
無
來源
Neuq Oj http://ncc.neuq.edu.cn/oj/problem.php?id=1105
1.問題分析
一般情況下,我們在做進位制轉換時,是利用除法來運算,同樣的,在進製為負數的時候,應該也是這樣的原理。
先舉個例子,將10轉換成2進位制:
商 餘數
2| 10
2| 5 0
2| 2 1
2| 1 0
2| 0 1 這樣結果就是1010了
那麼,再將10轉換成-2進位制就應該是這樣了:
商 餘數 始終記住餘數只能是0或者1
-2| 10
-2| -5 0
-2| 3 1 (正常情況下這一步應該是商為2,餘數為-1,但是餘數應為正,所以商+1)
-2| -1 1
-2| 1 1 (這一步也是)
-2| 0 1
這樣結果就是11110 [ 1*(-2)4+1*(-2)3+1*(-2)2+1*(-2)1+0*(-2)0=16-8+4-2+0=10]
同理,其他情況下也是這樣,具體數學證明過程我就不寫了= =(其實是不會寫)
2.我那弱弱的程式碼
#include<iostream>
#include<string.h>
#include<cstdio>
using namespace std;
int mod_s(int a,int b)
{
int s,y;
s=a/b;
y=a%b;
if(a<0&&b<0)
{
if(y!=0)
{s=s+1;y=a-b*s;}
else if(y==0)
{s=s;y=y;}
}
else
{s=s;y=y;}
return(s);
}
int mod_y(int a,int b)
{
int s,y;
s=a/b;
y=a%b;
if(a<0&&b<0)
{
if(y!=0)
{s=s+1;y=a-b*s;}
else if(y==0)
{s=s;y=y;}
}
else
{s=s;y=y;}
return(y);
}
int main()
{
int N,C,i,l,j,k,m,nn[1000],cc[1000],n,c;
k=0;
while(scanf("%d%d",&N,&C)==2)
{
nn[k]=N;
cc[k]=C;
k++;
}
for(m=0;m<k;m++)
{ n=nn[m];
c=cc[m];
char a[1000];
for(i=0;i>=0;i++)
{ if(0<=mod_y(n,c)&&mod_y(n,c)<=9)
{a[i]=mod_y(n,c)+48;}
else
{a[i]=mod_y(n,c)+55;}
if (mod_s(n,c)==0)
{break;}
n=mod_s(n,c);
}
l=strlen(a);
for(j=l-1;j>=0;j--)
{cout<<a[j];}
cout<<endl;
for(j=l-1;j>=0;j--)
{a[j]=NULL;}
}
return 0;
}
---------------------
作者:cq857174940
來源:CSDN
原文:https://blog.csdn.net/coffin5257/article/details/8228200?utm_source=copy
版權宣告:本文為博主原創文章,轉載請附上博文連結!
普通基數為正的進位制轉換中使用的都是短除法,即不斷的除以基數取整,把所有的餘數倒序輸出就是轉換完成之後的數了
但是對於基數為負數的進位制轉換,由於C/C++中模運算(%)的特性,餘數可能為負,當然不能簡單的取絕對值了事。
-5%-2=-1
網上找到了相關的處理方法,在此記錄一下:
在對負基數進位制進行轉換時,如果取模餘數為正,那麼就一切和正基數進位制轉換時一樣
但是當出現餘數為負時,進行如下操作:
將計算出的商加1
n = n/k+1; //n是原進位制的數,在求解過程中會不斷改變,k代表要轉換為k進位制
1
利用新的商乘以基數,再用被除數去減去這個結果,這樣就可以得到一個正數
n-(n/k+1)*k
1
使用這個結果當作餘數繼續進行求解即可
/*輸入要轉換的數和要轉換為幾進位制*/
#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;
char toChar[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
int mod(int n, int k){
if(n%k < 0)
return n-(n/k+1)*k;
else
return n%k;
}
int main(){
int n, k;
string ans;
while(cin>>n>>k){
ans = "";
cout<<n<<"=";
while(n){
ans = ans + toChar[mod(n, k)];
if(n%k < 0)
n = n/k+1;
else
n /= k;
}
reverse(ans.begin(), ans.end());
cout<<ans<<"(base"<<k<<")"<<endl;
}
return 0;
}
---------------------
作者:AutumnBloods
來源:CSDN
原文:https://blog.csdn.net/AutumnBloods/article/details/79437966?utm_source=copy
版權宣告:本文為博主原創文章,轉載請附上博文連結!