负进制转换

洛谷:1017进制转换 

        

我们可以用这样的方式来表示一个十进制数: 将每个阿拉伯数字乘以一个以该数字所处位置为指数,以 1010 为底数的幂之和的形式。例如 123123 可表示为 1×10^2+2× 10^1+3×10^0 这样的形式。

与之相似的,对二进制数来说,也可表示成每个二进制数码乘以一个以该数字所处位置为指数,以 22 为底数的幂之和的形式。

一般说来,任何一个正整数 RR 或一个负整数 -R−R 都可以被选来作为一个数制系统的基数。如果是以 RR 或 -R−R 为基数,则需要用到的数码为 0,1,....R-10,1,....R−1。

例如当 R=7R=7 时,所需用到的数码是 0,1,2,3,4,5,60,1,2,3,4,5,6,这与其是 RR 或 -R−R 无关。如果作为基数的数绝对值超过 1010,则为了表示这些数码,通常使用英文字母来表示那些大于 99 的数码。例如对 1616 进制数来说,用 AA 表示 1010,用 BB 表示 1111,用 CC 表示 1212,以此类推。

在负进制数中是用 -R−R 作为基数,例如 -15−15(十进制)相当于 110001110001 (-2−2进制),并且它可以被表示为 22 的幂级数的和数:

110001=1×(-2)^5+1×(-2)^4+0× (-2)^3+0× (-2)^2+0×(-2)^1 +1× (-2)^0

设计一个程序,读入一个十进制数和一个负进制数的基数, 并将此十进制数转换为此负进制下的数。

        我的方法中做负进制转换共有两步。

        一:用短除法像处理正常进制一样将所有余数算出来。例如(20)转换为-9进制,短除法算出来就是-22。然后我们逆推一下,-2*(-9)^1+2*(-9)^0=18+2=20;可以知道对于所有的进制和数都可以这样转换,只是出现了负数不符合逻辑。

        二:从低位到高位逐一处理(x为某一位,r为基)。若x<0,x=x-r,x下一位加一;若x==-r,x=0,x下一位减一。

        用(-2)进制举例吧,权重分别是(-8,4,-2,1)。对于第一种情况可以想象成x对结果的贡献值为负,而负进制的相邻位的权符号相反,只需要让比他大的一位加一,此位再减一个一样的数,那么结果自然不变,只是减去的数在此位表现为加上(-r)。比如第二位是-1,那么第三位先加1,就相当于加4,要使结果不变就需要减4,那就是-(-2)*(-2)。

        对于第二种情况就是x的贡献已经溢出,将当前位的数减掉恰好可以抵消下一位的一个1。

#include<iostream>
using namespace std;
void f(int n,int r,int pr)
{
	if (!n && !pr)
		return;
	int num = n % r + pr;
	pr = 0;
	if (num < 0) {
		num = num - r;
		pr = 1;
	}
	if (num == -r) {
		num = 0;
		pr=- 1;
	}
	f(n/r, r, pr);
	if (num >= 10)
		cout << char('A' + (num - 10));
	else
		cout << num;
}
int main()
{
	int n, r, i = 0;
	cin >> n >> r;
	cout << n << '=';
	f(n, r, 0);
	printf("(base%d)", r);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值