How to convert an integer to a string in any base?

前端 未结 27 3106
清歌不尽
清歌不尽 2020-11-22 02:25

Python allows easy creation of an integer from a string of a given base via

int(str, base). 

I want to perform the inverse: creati

相关标签:
27条回答
  • 2020-11-22 02:42

    You could use baseconv.py from my project: https://github.com/semente/python-baseconv

    Sample usage:

    >>> from baseconv import BaseConverter
    >>> base20 = BaseConverter('0123456789abcdefghij')
    >>> base20.encode(1234)
    '31e'
    >>> base20.decode('31e')
    '1234'
    >>> base20.encode(-1234)
    '-31e'
    >>> base20.decode('-31e')
    '-1234'
    >>> base11 = BaseConverter('0123456789-', sign='$')
    >>> base11.encode('$1234')
    '$-22'
    >>> base11.decode('$-22')
    '$1234'
    

    There is some bultin converters as for example baseconv.base2, baseconv.base16 and baseconv.base64.

    0 讨论(0)
  • 2020-11-22 02:44
    num = input("number")
    power = 0
    num = int(num)
    while num > 10:
        num = num / 10
        power += 1
    
    print(str(round(num, 2)) + "^" + str(power))
    
    0 讨论(0)
  • 2020-11-22 02:46

    Strings aren't the only choice for representing numbers: you can use a list of integers to represent the order of each digit. Those can easily be converted to a string.

    None of the answers reject base < 2; and most will run very slowly or crash with stack overflows for very large numbers (such as 56789 ** 43210). To avoid such failures, reduce quickly like this:

    def n_to_base(n, b):
        if b < 2: raise # invalid base
        if abs(n) < b: return [n]
        ret = [y for d in n_to_base(n, b*b) for y in divmod(d, b)]
        return ret[1:] if ret[0] == 0 else ret # remove leading zeros
    
    def base_to_n(v, b):
        h = len(v) // 2
        if h == 0: return v[0]
        return base_to_n(v[:-h], b) * (b**h) + base_to_n(v[-h:], b)
    
    assert ''.join(['0123456789'[x] for x in n_to_base(56789**43210,10)])==str(56789**43210)
    

    Speedwise, n_to_base is comparable with str for large numbers (about 0.3s on my machine), but if you compare against hex you may be surprised (about 0.3ms on my machine, or 1000x faster). The reason is because the large integer is stored in memory in base 256 (bytes). Each byte can simply be converted to a two-character hex string. This alignment only happens for bases that are powers of two, which is why there are special cases for 2,8, and 16 (and base64, ascii, utf16, utf32).

    Consider the last digit of a decimal string. How does it relate to the sequence of bytes that forms its integer? Let's label the bytes s[i] with s[0] being the least significant (little endian). Then the last digit is sum([s[i]*(256**i) % 10 for i in range(n)]). Well, it happens that 256**i ends with a 6 for i > 0 (6*6=36) so that last digit is (s[0]*5 + sum(s)*6)%10. From this, you can see that the last digit depends on the sum of all the bytes. This nonlocal property is what makes converting to decimal harder.

    0 讨论(0)
  • 2020-11-22 02:47

    I made a pip package for this.

    I recommend you use my bases.py https://github.com/kamijoutouma/bases.py which was inspired by bases.js

    from bases import Bases
    bases = Bases()
    
    bases.toBase16(200)                // => 'c8'
    bases.toBase(200, 16)              // => 'c8'
    bases.toBase62(99999)              // => 'q0T'
    bases.toBase(200, 62)              // => 'q0T'
    bases.toAlphabet(300, 'aAbBcC')    // => 'Abba'
    
    bases.fromBase16('c8')               // => 200
    bases.fromBase('c8', 16)             // => 200
    bases.fromBase62('q0T')              // => 99999
    bases.fromBase('q0T', 62)            // => 99999
    bases.fromAlphabet('Abba', 'aAbBcC') // => 300
    

    refer to https://github.com/kamijoutouma/bases.py#known-basesalphabets for what bases are usable

    EDIT: pip link https://pypi.python.org/pypi/bases.py/0.2.2

    0 讨论(0)
  • 2020-11-22 02:47
    def int2base(a, base, numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
        baseit = lambda a=a, b=base: (not a) and numerals[0]  or baseit(a-a%b,b*base)+numerals[a%b%(base-1) or (a%b) and (base-1)]
        return baseit()
    

    explanation

    In any base every number is equal to a1+a2*base**2+a3*base**3... The "mission" is to find all a 's.

    For everyN=1,2,3... the code is isolating the aN*base**N by "mouduling" by b for b=base**(N+1) which slice all a 's bigger than N, and slicing all the a 's that their serial is smaller than N by decreasing a everytime the func is called by the current aN*base**N .

    Base%(base-1)==1 therefor base**p%(base-1)==1 and therefor q*base^p%(base-1)==q with only one exception when q=base-1 which returns 0. To fix that in case it returns 0 the func is checking is it 0 from the beggining.


    advantages

    in this sample theres only one multiplications (instead of division) and some moudulueses which relatively takes small amounts of time.

    0 讨论(0)
  • 2020-11-22 02:47
    def baseConverter(x, b):
        s = ""
        d = string.printable.upper()
        while x > 0:
            s += d[x%b]
            x = x / b
        return s[::-1]
    
    0 讨论(0)
提交回复
热议问题