Skip to content

core: add int.bit_length()#2824

Closed
jepler wants to merge 1 commit into
adafruit:masterfrom
jepler:bit_length
Closed

core: add int.bit_length()#2824
jepler wants to merge 1 commit into
adafruit:masterfrom
jepler:bit_length

Conversation

@jepler
Copy link
Copy Markdown

@jepler jepler commented Apr 28, 2020

CPython has int.bit_length(), which returns the length of the number in bits.

I wanted this because it was required by a Fibonacci number calculator I wrote. However, as evidenced by the fact that upstream micropython hasn't implemented it either, I doubt it has wide applicability, so I won't be too sad if it's not incorporated.

On a CLUE I can calculate (and even print in decimal!) fib(65000) which is 13585 decimal digits long. The calculation takes about 9 seconds. Much larger than this, and the internal RAM is exhausted.

The program uses the matrix representation of the Fibonacci sequence, so that a result can be found by raising a matrix to a power, instead of by calculating sequentially all the numbers in the sequence up to the requested one.

class M2:
    def __init__(self, m00, m01, m10, m11):
        self.m00 = m00
        self.m01 = m01
        self.m10 = m10
        self.m11 = m11

    def __mul__(l, r):
        ret = M2(
            l.m00 * r.m00 + l.m01 * r.m10,
            l.m00 * r.m01 + l.m01 * r.m11,
            l.m10 * r.m00 + l.m11 * r.m10,
            l.m10 * r.m01 + l.m11 * r.m11
        )
        return ret

    def __pow__(self, exp):
        return fast_power(self, exp, self.mul_idn)

M2.mul_idn = M2(1, 0, 0, 1)

def fast_power(base, exp, mul_idn):
    result = mul_idn
    for i in range(exp.bit_length()):
        if exp & (1<<i):
            result *= base
        base *= base
    return result

def fib(n, mat=M2):
    return(mat(0,1,1,1) ** n).m11

I do not know why the updated builtin_help.py.exp removes two functions from the micropython module. It's unexpected by me.

@jepler
Copy link
Copy Markdown
Author

jepler commented Apr 28, 2020

I see the tests failed. It's another expected change, but for some reason I didn't encounter it locally. If there's interest in seeing this included, I'll fix it up. Otherwise, we can just close this and leave it for posterity. @tannewt thoughts?

@tannewt
Copy link
Copy Markdown
Member

tannewt commented Apr 28, 2020

My feeling is that it shouldn't be included. A helper python function can always do it and it wouldn't take up the flash space. (Lower power is out of space on two boards now which has me wary of adding else to the core objects.)

@jepler jepler closed this Apr 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants