连续对数算术:运行长度编码项的floor操作符

时间:2017-11-11 22:54:43

标签: python algorithm continued-fractions

我正在尝试对Bill Gosper的continued logarithms实施基本算术,这是一个连续分数的'变异',允许术语共同例程即使在非常大或非常小的数字上发出和消耗非常小的消息

可逆算术,例如{+, - ,*,/}由Gosper至少在一元表示中直接描述,但是我很难实现模运算符,它有效地截断了除法运算中的信息。 / p>

我已经意识到模运算符大部分都可以用我已有的运算来定义:

  

a mod b == a - b * floor(a / b)

留下我唯一的问题。

我还读到,持续对数的游程编码格式有效地描述了

  

'...剩余数量的对数库2的整数部分   描述'。

因此,立即产生第一个项(通过)会产生正确的输出,但是留下了一个重要的部分,我认为这需要某种进位机制。

我编写了以下代码来测试输入术语和预期的输出术语,但我主要是在实现底层后寻找高级算法的想法。

输出对的示例输入(1234/5)是

输入:[7,0,3,0,0,0,0,1,3,3,1]

输出:[7,0,3,1,4,2,1,1]

from fractions import Fraction

def const(frac):
        """ CL bistream from a fraction >= 1 or 0. """
        while frac:
                if frac >= 2:
                        yield 1
                        frac = Fraction(frac, 2)
                else:
                        yield 0
                        frac -= 1
                        frac = Fraction(1, frac) if frac else 0

def rle(bit_seq):
        """ Run-length encoded CL bitstream. """
        s = 0
        for bit in bit_seq:
                s += bit
                if not bit:
                        yield s
                        s = 0

def floor(rle_seq):
        """ RLE CL terms of the greatest integer less than rle_seq. """
        #pass
        yield from output

""" Sample input/output pairs for floor(). """
num = Fraction(1234)
for den in range(1, int(num)+1):
        input  = list(rle(const(num  / den)))
        output = list(rle(const(num // den))) # Integer division!
        print(">  ", input)
        print(">> ", output) 
        print(">>*", list(floor(input))) 
        print()
        assert(list(floor(input)) == output)
  

如何以持续的精神实施楼层操作员   通过仅在必要时使用术语来进行分数算术   立即发出条款,特别是只使用游程   编码格式(二进制)而不是一元扩展Gosper   倾向于描述。

1 个答案:

答案 0 :(得分:0)

通过假设游程长度编码中的下一个系数是无限的,您可以得到一个下限。通过假设下一项为1,您可以得到一个上限。

您可以简单地处理多个游程编码系数,直到您知道上下限都在半开区间[N,N + 1]中。在这种情况下,您知道连续对数的下限是N。这类似于Bill Gosper在链接文档的开头所做的事情。

但是请注意,此过程不一定会终止。例如,当将sqrt(2)乘以sqrt(2)时,当然会得到数字2。但是,sqrt(2)的连续对数是无限的。要评估乘积sqrt(2)* sqrt(2),您将需要所有系数来知道最终将得到2。对于有限数量的项,您无法确定乘积小于2还是等于至少等于它。

请注意,此问题并非特定于连续对数,而是在任何系统中都存在的基本问题,在该系统中,您可以具有两个表示无穷大的数字,但乘积可以表示成有限数量的系数

为了说明这一点,假设这些协程不吐出游程编码的值,而是吐出十进制数字,并且我们要计算floor(sqrt(2)* sqrt(2))。经过几步后,我们可以确定乘积至少为2?让我们用11位数字来看看会发生什么: 1.41421356237 * 1.41421356237 = 1.9999999999912458800169

您可能会猜到,我们任意接近2,但是永远不会“达到”2。确实,在不知道数字来源为sqrt(2)的情况下,数字可能会在此点之后终止并且该乘积最终小于2。类似地,以下所有数字都可能为9,这将导致乘积略高于2。

(一个更简单的示例是生成0.9999 ...的例程的地板。)

因此,在这种任意精度的数值系统中,您可能会遇到只能计算某个间隔(N-epsilon,N + epsilon)的情况,在这种情况下,您可以使ε任意小,但从不等于零。不可能对此表达式进行讨论,因为-使用所采用的数值方法-无法确定实际值最终会低于N还是。