将一个以10为基数的数字转换为另一个基数

convert a number from base-10 to another base

本文关键字:转换 另一个 数字 一个以      更新时间:2023-10-16

我尝试了以下代码将一个数字从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;

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

这是工作程序。

#include <iostream>
void printInBase(int x, int y)
{
   if ( x < y )
   {
      std::cout << x;
      return;
   }
   int rem = x%y;
   printInBase(x/y, y);
   std::cout << rem;
}
int main()
{
   int x, y;
   std::cout << "enter two numbers" << std::endl;
   std::cin >> x >> y; // x as the number in base-10 and x, as the destination base
   printInBase(x, y);
   std::cout << 'n';
}
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)之类的东西来解决这个问题,或者像我在上面的代码中所做的那样,提前计算出你需要多少数字。

尽管它可以工作,但这种方法在概念上存在错误:你本质上混淆了数字(算术运算的主题)和它们的文本表示(用于表示它们的数字序列)。

从外部角度来看,类型int没有"基数"(int很可能有一个基数为2的内部表示,它的功能是由算术单元电路操纵的):它只是一个需要添加、减去、多重、除法和ed、xor ed等的东西。

当您执行cout << a时,<<所做的就是将a数字转换为一个数字序列,将其表示为可读的内容。默认情况下,它恰好以ASCII字符("0"…"9")表示的10位为基数

您正在做的是将一个数字转换为另一个数字,该数字的十进制表示形式与您正在映射的基数相似。它可以在打印中工作,但没有算术可以使用它。因此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')等,但考虑到普通数字,这并不是所需要的。

我的答案。

也适用于浮点数

#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);
}
相关文章: