问题
I'm trying to implement basic arithmetic on Bill Gosper's continued logarithms, which are a 'mutation' of continued fractions allowing the term co-routines to emit and consume very small messages even on very large or very small numbers.
Reversible arithmetic, such as {+,-,*,/} are fairly straightforwardly described by Gosper at least in a unary representation, but I'm having difficulty implementing the modulo operator which effectively truncates information from the division operation.
I've realized the modulo operator can be mostly defined with operations I already have:
a mod b == a - b * floor(a / b)
leaving my only problem with floor.
I've also read that the run-length encoded format for continued logarithms effectively describes
'... the integer part of the log base 2 of the number remaining to be described.'
So yielding the first term right away (pass through) produces the correct output so far, but leaves a significant portion to be determined which I assume requires some sort of carry mechanism.
I've written the following code to test input terms and the expected output terms, but I'm mainly looking for high level algorithm ideas behind implementing floor.
An example input (1234 / 5) to output pair is
Input: [7, 0, 3, 0, 0, 0, 0, 1, 3, 3, 1]
Output: [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)
How can I implement the floor operator in the spirit of continued fraction arithmetic by consuming terms only when necessary and emitting terms right away, and especially only using the run-length encoded format (in binary) rather than the unary expansion Gosper tends to describe.
来源:https://stackoverflow.com/questions/47243679/continued-logarithm-arithmetic-floor-operator-on-run-length-encoded-terms