题目描述
以前我们做的进制转换大家都忽略了一点,就是进制一定是正整数;今天这道进制转换就坑爹的选择了,额,负整数来做进制。
输入
输入由若干行组成,每行有两个整数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
版权声明:本文为博主原创文章,转载请附上博文链接!