将数字从base-10转换为另一个base

时间:2014-10-21 18:29:29

标签: c++

我尝试使用以下代码将数字从base-10转换为另一个基数。如果目标库中没有零(0),它可以工作。检查79和3并正确打印2221,这是正确的。 现在尝试编号19和3,结果将是21而不是201表示出现了问题。

int x, y, a = 0, i, t, j;
cout << "enter two numbers" << endl;
cin >> x >> y; // x as the number in base-10 and x, as the destination base
a = x;
while (x >= y)
{
    t = 1;
    for (i = 0; x > y; i++)
    {
        x /= y;
    }
    cout << x;
    for (j = 0; j < i; j++)
    {
        t *= y;
    }
    a = a - (t*x);
    x = a;
}
cout << x<<endl;

4 个答案:

答案 0 :(得分:1)

使用递归函数比使用while循环更容易实现。

这是工作计划。

#include <iostream>
using namespace std;

void printInBase(int x, int y)
{
   if ( x < y )
   {
      cout << x;
      return;
   }

   int rem = x%y;
   printInBase(x/y, y);
   cout << rem;
}

int main()
{
   int x, y;
   cout << "enter two numbers" << endl;
   cin >> x >> y; // x as the number in base-10 and x, as the destination base
   printInBase(x, y);
   cout << endl;
   return 0;
}

答案 1 :(得分:0)

int x, y, a = 0, i, t, j;
cout << "enter two numbers" << endl;
cin >> x >> y; // x as the number in base-10 and x, as the destination base
a = x;

t = 1;
while (x >= t*y)
{
    t = t * y;
}

while (t)
{
    cout << x/t << ' ';
    x -= t*(x/t);
    t /= y;
}

cout << '\n';

基本上你没有跟踪你打印出的数字,而你的代码无法告诉它何时需要前导零。您可以通过打印类似2*(3^2) + 1*(3^0)的内容或通过确定您需要提前多少位数来解决这个问题,就像我在上面的代码中所做的那样。

答案 2 :(得分:0)

尽管它可行,但在这种方法中存在一些概念上的错误:你基本上将数字(算术运算的主题)与它们的文本表示(用于表示它们的数字序列)混淆。

类型int - 从外部角度来看 - 没有&#34; base&#34; (int很可能有一个base-2内部表示,它的功能是由算术单元电路操作的):它只是一个要添加的东西,减去多重,分割,以及-ed,xor-ed等。

cout << a执行<<时,将a数字转换为表示可读的内容的数字序列。默认情况下,它恰好用基数为10的数字表示为ASCII字符(&#39; 0&#39; ...&#39; 9&#39;)。

您正在做的是将数字转换为另一个数字,其十进制表示形式类似于您要映射的基数。它可以在打印中工作,但没有可以使用它的算法。所以int不适合他们。

你需要的是一个不同的文本转换器:需要int和另一个指定基数的int,并吐出字符来表示你的数字。

想想像

这样的课程
class based
{
   int n, base;
public:
   based(int num, int base) :n(num), base(base) {}

   friend std::ostream& operator<<(std::ostream& out, const based& x);
};

用作

std::cout << bsed(79,3) << ' ' << based(19,3) << std::endl;

现在

std::ostream& operator<<(std::ostream& out, const based& x)
{
    static const size_t N = 8*sizeof(int)+2; //base 2 is the widest, and is 32 or 64 + 2
    char buff[N]; //keep space for sign + base2 + terminator
    size_t X = N-1; //current writing character position
    buff[X] = 0; //terminating char
    --X; //prepare next left character
    int n = x.n; //we will work on n
    bool neg = (n<0); //keep negative sign
    if(neg) n=-n; //and work always with posiotives
    while(n) //we will reduce n down to 0
    {
        int digit = n%x.base; //mod is the last digit
        n /= x.base; //next to the left
        buff[X] = (digit<10)? char(digit+'0'): char(digit-10+'A');
        --X; //next char 
    }
    if(neg) buff[X] = '-'; 
    else ++X; //no sign
    out << buff+X << '(' << x.base << ')'; //the text from the point we reach towards left
    return out; 
}

这将输出2221(3) 201(3)

还有一种更便携的方式char(digit+'0')等,但考虑到正常数字,这不仅仅是需要的东西。

答案 3 :(得分:0)

我的答案。

还将对浮点数起作用

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void radix(char *strNum, int base);

int main ()
{
    radix("215.75", 8);
    return 0;
}

void swap(char *a, char *b)
{
    char temp = *a;
    *a = *b;
    *b = temp;
}

void radix(char *strNum, int base)
{
    char res[100]={0}, tmp[100]={0}, floPoint[100]={0}, *p = 0, *q = 0;
    int inum = 0, digitAfterDot = 3;
    float fnum = 0.0;
    if(strchr(strNum, '.'))
    {
        p = strNum + strcspn(strNum, ".");
        fnum = atof(p);
    } 
    inum = atoi(strNum);
    for(p = res; inum; inum /= base, p++)
        *p = (inum % base) + '0';
    *p = 0;
    if(fnum != 0.0)
    {
        p = floPoint;
        *p++ = '.';
        for(fnum *= base; digitAfterDot--; p++, fnum *= base)
        {
            sprintf(tmp, "%f", fnum);
            inum = atoi(tmp);
            fnum -= inum;
            *p = inum + '0';
        }
        *p = 0;
    }
    for(p = res, q = res+strlen(res)-1; p < q; p++, q--)
        swap(p, q);
    strcat(res, floPoint);
    puts(res);
}