将 BigNum(带重复数字的二进制)转换为十进制

问题描述 投票:0回答:1

我目前有一个基于有理数(带有重复数字)的大数实现,它存储以下内容(二进制):

  • 整数部分
  • 分数部分
  • 重复分数部分

一些例子(表示为

<int>.<frac>(<repeating-frac>)
):

  • 2.5
    (基数 10):
    10.1
    (基数 2)
  • 2.1
    (基数 10):
    10.0(0011)
    (基数 2)
  • 2.5(3)
    (基数 10):
    10.(1000)
    (基数 2)

我可以使用以下过程从基数 10(或任何基数)转换为基数 2(这是大数字实际存储在磁盘上的方式):

  • 对于整数部分,只需将它(字符串除法)除以 2 直到它为 0。

    在这种情况下,每次除法后的余数编码数字。

  • 对于小数部分,继续乘以(字符串乘法)2,直到它为 0,或者在循环中。

    • 如果我们得到 0,我们只有分数部分,没有重复分数。
    • 如果我们进入一个循环,循环之前的所有数字都进入小数部分,所有其他数字进入重复小数部分。

    无论哪种情况,乘法的“余数”/溢出都会对小数部分进行编码。

从基数 2 转换为基数 10(或任何其他基数)时会出现问题。我目前有以下程序:

  • 通过反转过程并乘以 2 并添加所有数字的余数来获得整数部分。

  • 通过添加“余数”/溢出并除以 2 得到纯小数(非重复)部分

然而,对于重复的小数部分,我不知道如何开始。在解码整数或纯小数时,我从0开始,因为编码过程以0结束。但是对于重复的小数部分,结束值不是0,所以我不能从0开始并期望获得相同的价值。

我不想存储这个停止号,因为我知道,例如,

0.0(0011)
(基数 2)唯一且明确地映射到
0.1
(基数 10)。任何数字组合也是如此。它们都应该映射到一个唯一的小数(或任何其他基数)等价物。

鉴于此,我不想浪费存储最终值的空间,因为必须有一种方法可以恢复到原始值。

那么我怎样才能从基数 2 编码(有重复数字)到基数 N 编码(可能有重复数字)

如果通用基数不可能,我只对基数 8、10 和 16 真正感兴趣,其中 8 和 16 是微不足道的,因为它们是 2 的幂,所以 10 是我真正关心的唯一其他基数转换为基数 2.

fractions bignum
1个回答
0
投票

事实证明,答案相对简单:我们只需要执行与从基数 N 转换为基数 2 时相同的算法,但不是将基数 N 的字符串除以/乘以 2,而是将基数 N 的字符串除/乘以 2 N.

以 2 为底的字符串

这是与问题中相同的算法,现在对基数 N 通用:

  • 对于整数部分,简单地一直除以N直到它为0。

    在这种情况下,每次除法后的余数编码以 N 为底的数字。

  • 对于小数部分,一直乘以N直到它为0,或者在一个循环中。

    • 如果我们得到 0,我们只有分数部分,没有重复分数。
    • 如果我们进入一个循环,循环之前的所有数字都进入小数部分,所有其他数字进入重复小数部分。

    无论哪种情况,乘法的“余数”/溢出都会对基数 N 中的小数部分进行编码。

现在这确实使实际实现变得复杂,因为字符串除以/乘以 2 比二进制除以/乘以 N 容易得多,所以也许可以仅使用字符串操作来实现它,就像问题中的原始解码算法对整数所做的那样和非重复小数,但这可能比使用二元运算需要更多的工作。

© www.soinside.com 2019 - 2024. All rights reserved.