将数字从Base B1转换为Base B2,而不使用任何中间基数

时间:2010-08-18 15:31:49

标签: java c++ c algorithm numbers

有没有办法在不使用任何中间基础的情况下将数字从Base B1转换为Base B2。

例如:

214从base 5到base 16,不先将其转换为十进制,然后再将十进制转换为十六进制。

-

由于

Alok Kr。

7 个答案:

答案 0 :(得分:8)

这只是我们使用十进制系统的一个假象。因此,您希望(在您的脑海中)想到十进制中每个数字的“值”。因此,您将所有内容转换回基数10.如果您知道如何在其他基础上进行除法和乘法,那么在不使用基数10作为中间数的情况下来回转换将很容易。然而,大多数人通常不做基数5除法/乘法,并且会将所有内容转换回基数10。

算法是一样的。除以新基数的最大功率,然后将剩余部分除以较小的功率,你将得到新的基数。

例如0x3B到基数5.

(数学基础16)

3B / 5 ^ 2 = 2余数9

9/5 = 1余数4

所以0x3B = 214 base 5

如果你知道如何做非基础10师,那很简单。但是,绝对没有理由去了解它,因此转换回基数10作为中间步骤要容易得多。

但是,有一种简单的方法可以在二进制和十六进制之间进行转换。只需将数字拆分为4个二进制/ 1个十六进制数字的组,然后逐位转换。

1111 0000 1100 0001 
   F    0    9    1

答案 1 :(得分:7)

不确定你的意思。这些语言中的数字不在基数10(如果有的话,它们是基数2) - 当您将数字格式化为字符串时,您可以用基数格式化它。

因此,如果您有一个数字的字符串表示形式并将其转换为数字,然后将其格式化为不同的基础 - 您不会转换为基数10 - 您将字符串转换为int转换为字符串。

所以,如果问题是我如何获取表示基本B1中的数字的字符串并将其转换为基本B2中的字符串而不将其转换为int,那么我看不到有办法轻松地做到这一点。

在你的示例中,基数5中的214是2*5^2 + 1 * 5 + 4 - 但是如果你不想转换为int,那么你就不知道了。这个数字在基数10中是59,但计算机将其视为00111011.您可以轻松地将其格式化为十六进制。最终,你需要进行除法和乘法运算,并将中间结果存储在某处。

答案 2 :(得分:7)

要将214 base5 转换为没有中间基础的基础16,您“只需”知道如何直接在基数5中计算。

首先,你需要一个基数为16的基数为5的表格(你需要一个类似的表格,将基数10转换为基数为16时,只需要更容易保留在你的脑中!)。这个表很容易创建 - 只需从0开始并递增每个基数为5行,直到你到达基数为16的f

base 16 | base 5
--------+--------
      0 |  0
      1 |  1
      2 |  2
      3 |  3
      4 |  4
      5 | 10
      6 | 11
      7 | 12
      8 | 13
      9 | 14
      a | 20
      b | 21
      c | 22
      d | 23
      e | 24
      f | 30

现在你只需要重复除以16(即31 base5 )。我们现在回想起我们的小学时代,并且使用长分(如果这看起来很难,那是因为没有人让你在5号基础上学习你的时间表!):

第1步:

   ______
31 ) 214

第2步:

       3 
   ______
31 ) 214 -
     143  

第3步:

       3 
   _____
31 ) 214 -
     143  
    ----
      21

因此214 base5 除以31 base5 的结果为3 base5 余数21 base5

这意味着base16中的最低有效位是21 base5 ,您可以在表中找到b base16 。除法的结果是3 base5 - 如果这大于30 base5 那么我们将再次划分 - 但它不是,所以这意味着最重要的数字是(使用再次表格)3 base16

所以答案是214 base5 = 3b base16

答案 3 :(得分:3)

我不相信有任何“语法技巧”可以让你为一般的基本转换做到这一点。 (例如,允许您从字符串“214”转到字符串“3B”而不确定哪个整数“214”(基数5)实际对应的技巧。)

我的意思是你必须知道你将使用的数字的,也就是说,你需要“解析”输入。

例如,基数5中的

214将被解析为2 * 5 2 + 1 * 5 + 4.通过执行此类计算,您将无法以十进制形式获得它。你会得到它的形式,你的计算机决定将结果整数存储在(可能是二进制:)

从那时起你就可以轻松输出数字,比如16号。(注意你没有经过10号基地。)正如@Lou Franco所说,你只是从 string-> int-> string ,而不是 string-> string

答案 4 :(得分:2)

是和否。是,如果您不包括计算机以二进制(基数2)作为另一种表示形式执行所有操作的事实。毕竟,以下代码中value的基础是什么?

long value = strtol(string, NULL, base);

在某些意义上,value只是一个整数,并且没有关联的基数。将它与一个函数结合起来,可以在一个特定的基础中将值从一个值转换为字符串表示,并且您可以轻松地从一个基础中的字符串表示形式转换为另一个基础中的字符串表示形式。由于没有中间字符串表示,因此在某种意义上,没有中间基本值。

答案 5 :(得分:0)

也许你可以创建一个代表每个基础的类。该类将有一系列字段来表示每个数字 - 例如,Decimal类将具有单位字段,数字字段,数百个字段等等。然后编写mutators以从对象表示的值(和字段之间的句柄)中添加或减去一个,以及一个允许您检查值是否为零的访问器。在输入数字的基础上创建一个对象(可能写一个解析字符串的方法?)和一个值为零的所需基数中的对象。然后有一个循环,你从输入数字中减去一个,然后在输出数字上加一,直到输入数字达到零。

如果你通过解析字符串来创建对象,你可以避免问题aioobe指出你将数字表示为二进制,尽管你可以说是使用一元表示。稍微想一想,你也可以使基类足够通用,以处理任意数量的基数。

答案 6 :(得分:0)

将它们存储为int,然后在需要代表它们时进行转换,如std::ios_base does.