【p1017-进制转换】解题记录

查看原题点 这里

这道题说到底还是用短除法递推求解。只是基数从整数变成了负数,所以相应的过程有细微的变化。

p.s. 短除法的原理可以看之前写的 进制转换的原理

负基数的短除法

过程与原来的短除法相似,这次以 -2 为基数举例。

设原来的十进制数为 n,转换后的 -2 进制数为 abcd(当然结果不一定是 4 位数,只是举个例子)。

现在已知 x,求 abcd,那么写出等式:

(abcd)2=(n)10

将左边转换为 10 进制,得到:

a×(2)3+b×(2)2+c×(2)1+d×(2)0=n

除了最后一项 d 外,前几项都有公因式 -2,于是因式分解:

2×(a×(2)2+b×(2)1+c)+d=n

简便起见,将 a×(2)2+b×(2)1+c 简写为 k,于是等式变成:

2k+d=n

如果把 n 看成被除数,-2 看成除数,k 看成商,d 看成余数,那么等式就可以写成:

n÷(2)=kd

至此所有的步骤与正基数的短除法相同。下面就是本题最有趣的部分。

我们都知道余数和被除数的符号是相同的。

当 n 大于等于 0 时,处理方式还是和原来一样的。但是如果 n 小于 0 的话,那么 d 也会小于 0,但是我们知道 d 一定是在 [0, 2) 范围内的正整数,所以就需要对等式进行一些变换,使得余数大于等于 0:

n÷(2)=k+1d+2

也就是说,把商加一,余数再减去一个除数,等式还是成立的。因为余数的绝对值一定是小于除数的绝对值,因此减去一个除数(相当于加上除数的绝对值)就能令余数非负,此时就能继续像以前一样计算了。

总结一下就是:还是用短除法,只是当余数小于 0 时,把商加一,把余数减去除数(即基数)使之为正,并保持等式成立,然后就直接像往常一样计算就行了。

代码

#include <cstdio>
using namespace std;

int ans[105], end=0;

int main(){
    int num, base;
    scanf("%d%d", &num, &base);

    for(int x=num, rst=0, mod=0; x!=0;){
        rst= x/base;
        mod= x%base;
        if(mod<0){
            mod-= base;
            rst+= 1;
        }
        ans[end++]= mod;
        x= rst;
    }

    printf("%d=", num);
    for(int i=end-1; i>=0; --i){
        int ch= ans[i];
        if(ch<10) putchar('0'+ch);
        else putchar('A'+ch-10);
    }
    printf("(base%d)\n", base);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值