1. 程式人生 > >負進位制轉換

負進位制轉換

 

題目描述

以前我們做的進位制轉換大家都忽略了一點,就是進位制一定是正整數;今天這道進位制轉換就坑爹的選擇了,額,負整數來做進位制。

輸入

輸入由若干行組成,每行有兩個整數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 
版權宣告:本文為博主原創文章,轉載請附上博文連結!