进制转换问题详解

算法
ATTAINTION: 由于HEXO目前对于MathJax的支持不甚完善,如果数学公示渲染错误请刷新或前往我的LUOGU博客以获最佳体验
Published

July 16, 2019

CautionContent note — Known errors · 明显错误

进制转换文章把普通整数进制推广成任意实数进制,并且数字集合定义不正确。

  • 普通位权表示通常要求整数基数且绝对值大于 1,不能直接写成任意 r ∈ R
  • 数码应允许 0,且通常范围是 0 <= digit < base,不是正整数集合。
  • 示例代码未处理 0、负数、十六进制以上字符等边界。

ATTAINTION: 由于HEXO目前对于MathJax的支持不甚完善,如果数学公示渲染错误请刷新前往我的LUOGU博客以获最佳体验

关于进制转换的问题最详细解释

1.前言

很久前曾经系统学习过进制转换的问题,但发现…忘了?!好吧所以就再重新学习下然后写篇博客吧。这次可不要再不求甚解了。

那么就开始吧,先说下最基础的,如何把十进制数 a 转化为任意正 r 进制数。

在十进制下$n Z \(,都可以将它表示为\)$ A_1{n-1}+A_2{n-2}+…+A_n^{0} $$ 其中 \({A\_i}\in{Z}^{+}\) ,其中的 \({A}\_{i}\) 就是这个整数每一位的值。很显然的可以对它进行推广,\(\forall\) r \(\in\) R 都有以上结论成立。很显然我们要做的就是获得在 r 进制下的\(A_i\)的值。获得方法也很简单。那就是将这个整数对 r 不停地取模,然后将它除以 r 向下取整。稍微考虑下就可以发现它的原理(如果是特殊情况的话需要稍加更改,比如负进制)。

下面举个简单的例子,将十进制下的 6 转换为二进制。按照刚才的步骤,将其对 2 取模,发现是零,这里的意义其实就是, 6 在二进制下的最后一位是 0 ,因为它 %2 为零,就说明它不需要 \(2^0\) 这个数所以这一位为0,就是我们上面所讲\(A\_1\)=0。的这是很显然的。然后让 6 / 2 得到 3 这就相当于对于 6 的二进制数忽略掉最后一位重复刚才的过程。因为100(base2)相当于10*2(base2)对吧。那么再让 \(3\%2\) ,得到 1 ,刚才讲到,这里的 1 默认是乘以二的所以就说明 6 需要 \(2^{0+1}\) 就是\(2^1\) 那么1就是前面我们所讲到的\(A\_{2}\)。我们一直重复刚才的过程就可以得到 6 的二进制表示:110

即为\(1 \times 2^{2}+1 \times 2^{1}+0 \times 2^{0}\)很简单吧_

2.代码

#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
stack <int> s;
int main(){
    int n,r;
    scanf("%d%d",&n,&r);   //十进制数 n 再 r 进制下 
    int t;
    while(n){
        t=n%r;
        s.push(t);     //因为我们是从后向前计算的,所以就用个栈存下
        n/=r;              //c++向零取整
    }
    while(!s.empty()){
        cout<<s.top();
        s.pop();
    } 
    return 0;
}