기본에서 정수를 문자열로 변환하는 방법은 무엇입니까?


202

파이썬은 주어진 기본 문자열에서 정수를 쉽게 만들 수 있습니다.

int(str, base). 

나는 inverse : integer에서 문자열 생성 을 수행하고 싶습니다. 즉 int2base(num, base), 다음과 같은 함수를 원합니다 .

int(int2base(x, b), b) == x

함수 이름 / 인수 순서는 중요하지 않습니다.

어떤 번호 x와 기본 bint() 받아 들일 것입니다.

이것은 작성하기 쉬운 함수입니다. 실제로이 질문에서 설명하는 것보다 쉽습니다. 그러나 뭔가 빠진 것 같아요.

나는 기능에 대해 알고 bin, oct, hex,하지만 몇 가지 이유를 사용할 수 없습니다 :

  • 이 함수는 이전 버전의 Python에서는 사용할 수 없으며 (2.2)와 호환되어야합니다.

  • 다른 기지에 대해 같은 방식으로 호출 할 수있는 일반적인 솔루션을 원합니다.

  • 2, 8, 16 이외의 기지를 허용하고 싶습니다

관련


5
놀랍게도 아무도 임의의 큰 염기 (1023)와 함께 작동하는 솔루션을 제공하지 않았습니다. 필요한 경우 모든 기본 (2 ~ inf)에서 작동하는 솔루션을 확인하십시오. stackoverflow.com/a/28666223/1090562
Salvador Dali

답변:


98

고대 버전의 Python과의 호환성이 필요한 경우 gmpy 를 사용할 수 있습니다 (빠르고 완전히 일반적인 int-to-string 변환 함수를 포함하고 이러한 고대 버전을 위해 빌드 될 수 있음) 최신 버전은 유능한 Python 및 GMP 릴리스, 일부 최신 버전에 대해서만 테스트되지 않았거나 속도는 느리지 만 편리 성을 위해 Python 코드를 사용하십시오.

import string
digs = string.digits + string.ascii_letters


def int2base(x, base):
    if x < 0:
        sign = -1
    elif x == 0:
        return digs[0]
    else:
        sign = 1

    x *= sign
    digits = []

    while x:
        digits.append(digs[int(x % base)])
        x = int(x / base)

    if sign < 0:
        digits.append('-')

    digits.reverse()

    return ''.join(digits)

8
(gmpy2) 경우에 Alex가 말하는 func는입니다 gmpy2.digits(x, base).
mlvljr 2012 년

2
어떤 경우에는 36보다 큰 기지가 필요하므로 발굴이 이루어져야한다는 점에주의를 기울였습니다.digs = string.digits + string.lowercase + string.uppercase
Paul

4
(나 string.digits + string.letters)
코지로

3
파이썬에서 기본적으로 N을 문자열로 변환하지 않는 이유는 무엇입니까? (자바 스크립트로되어 있습니다.) 예, 우리는 모두 자체 구현을 작성할 수 있지만이 사이트와 다른 곳에서 검색을 해왔으며 많은 버그가 있습니다. 핵심 배포판에 테스트되고 평판이 좋은 버전을 포함시키는 것이 좋습니다.
Jason S

4
@ lordscales91 또한 파이썬 2에서 x //= base와 같이 /=소수점을 삭제하는 데 사용할 수 있습니다 . 이 답변에는 파이썬 2에 대한 면책 ​​조항이 포함되어야합니다.
Noumenon

100

놀랍게도 사람들은 작은 염기 (영어 알파벳 길이보다 작은)로 변환하는 솔루션 만 제공하고있었습니다. 2에서 무한대로 임의의 염기로 변환하는 해를 제공하려는 시도는 없었습니다.

다음은 매우 간단한 솔루션입니다.

def numberToBase(n, b):
    if n == 0:
        return [0]
    digits = []
    while n:
        digits.append(int(n % b))
        n //= b
    return digits[::-1]

그래서 당신은베이스에 약간의 슈퍼 거대한 숫자로 변환해야하는 경우 577,

numberToBase(67854 ** 15 - 102, 577)올바른 솔루션을 제공합니다. [4, 473, 131, 96, 431, 285, 524, 486, 28, 23, 16, 82, 292, 538, 149, 25, 41, 483, 100, 517, 131, 28, 0, 435, 197, 264, 455] ,

나중에 원하는베이스로 변환 할 수있는


대학에서 나는 20 이하의 밑줄을 표준 표기법으로, 20 이상의 밑줄을 '콜론으로 구분 된 십진수'로 형식화하는 기능을 고안했습니다. 예를 들어 int(4545,16)"11c1"과 int(4545,60)"1:15:45"를 제공했습니다. 따라서이 함수는 십진, 컴퓨터 및 타임 스탬프 형식으로 변환하는 세 가지 의무를 수행했습니다.
Peter Raynham

1
이 방법의 역함수는 무엇입니까?
Sohrab T

이것은 3 가지 이유에 대한 질문에 대답하지 않습니다 .1 : 구현이 아닌 기존 라이브러리 함수에 대한 질문 2 : 문자열에 대한 질문, 목록을 생성합니다 .3 : int (str, 기본) 내장.
플러그 워시

@plugwash 1) 어떤 시점에서 때로는 원하는 것을 수행하는 내장 라이브러리 기능이 없으므로 직접 작성해야합니다. 동의하지 않는 경우 기본 10 숫자를 기본 577로 변환 할 수있는 내장 함수를 사용하여 자체 솔루션을 게시하십시오. 2) 이는 일부 기본 숫자가 무엇을 의미하는지 이해하지 못하기 때문입니다. 3) 왜 메소드의 기본이 n <= 36에서만 작동하는지 조금 생각할 것을 권장합니다. 일단 완료되면 내 함수가 왜 목록을 반환하고 서명이 있는지 분명히 알 수 있습니다.
살바도르 달리

1
이것은 음수에는 작동하지 않으며 기본적으로 변경하지 않고 작동시키는 방법을 모르겠습니다. digits? 의 맨 위에 부호 비트 1 또는 -1을 추가하면됩니다 .
wjandrea

89
def baseN(num,b,numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
    return ((num == 0) and numerals[0]) or (baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b])

심판 : http://code.activestate.com/recipes/65212/

이로 인해

RuntimeError: maximum recursion depth exceeded in cmp

매우 큰 정수의 경우.


5
간결하게 우아합니다. 음이 아닌 정수의 경우 Python 2.2.3에서 작동하는 것 같습니다. 음수는 무한히 반복됩니다.
Mark Borgerding

유용한 +1; 숫자가 '0'으로 시작하지 않을 때의 문제가 수정되었습니다.
sehe

4
이것은 (a) base가> len(numerals)이고 (b) num % b운이 좋으면 < len(numerals)입니다. 예를 들어 numerals문자열의 길이는 36 자 '1k'이지만 baseN (79, 40)은을 반환 하는 동안 baseN ( 60, 40)은 반환 IndexError됩니다. 둘 다 일종의 오류를 발생시켜야합니다. 오류가 발생하도록 코드를 수정해야합니다 not 2 <= base <= len(numerals).
Chris Johnson

3
@ osa, 내 요점은 작성된 코드가 매우 나쁜 방식으로 실패하고 (자동으로 오해의 소지가 있음) 쉽게 해결할 수 있다는 것입니다. 당신이 미리 알고 있다면 오류가 없을 것이라고 말하면, 그것은 당신에게 행운을 b초과하지 않을 len(numerals)것입니다.
크리스 존슨

1
여기서 단락을 사용하는 것은 불필요하게 혼란스러워 보입니다 ... 왜 if 문을 사용하지 않는지 ... 줄 return numerals[0] if num == 0 else baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b]은 간단합니다.
Ian Hincks 2016 년

83
"{0:b}".format(100) # bin: 1100100
"{0:x}".format(100) # hex: 64
"{0:o}".format(100) # oct: 144

46
그러나 그것은 단지 세 가지 기초를 수행합니까?
Thomas Ahle

3
예, 불행히도 사용자 정의 int base를 지정할 수 없습니다. 더 많은 정보는 여기에 있습니다 : docs.python.org/library/string.html#formatstrings
Rost

3
0불필요합니다. 다음은 Python 2 설명서입니다. docs.python.org/2/library/string.html#format-string-syntax
Evgeni Sergeev

7
당신과 같은 결과를 얻을 수 있습니다 hex(100)[2:], oct(100)[2:]하고 bin(100)[2:].
Sassan

2
@ EvgeniSergeev : 2.7 / 3.1 +에서만 불필요합니다. 2.6에서는 명시 적 위치 (또는 이름)가 필요합니다.
ShadowRanger

21

좋은 답변입니다! 내 질문에 대한 대답이 "아니오"라고 생각합니다. 확실한 해결책이 없었습니다. 다음은 답변에 표현 된 좋은 아이디어를 요약하는 데 사용할 기능입니다.

  • 발신자 제공 문자 매핑 허용 (base64 인코딩 허용)
  • 음수 및 0 확인
  • 복소수를 튜플의 문자열로 매핑


def int2base(x,b,alphabet='0123456789abcdefghijklmnopqrstuvwxyz'):
    'convert an integer to its string representation in a given base'
    if b<2 or b>len(alphabet):
        if b==64: # assume base64 rather than raise error
            alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
        else:
            raise AssertionError("int2base base out of range")
    if isinstance(x,complex): # return a tuple
        return ( int2base(x.real,b,alphabet) , int2base(x.imag,b,alphabet) )
    if x<=0:
        if x==0:
            return alphabet[0]
        else:
            return  '-' + int2base(-x,b,alphabet)
    # else x is non-negative real
    rets=''
    while x>0:
        x,idx = divmod(x,b)
        rets = alphabet[idx] + rets
    return rets


4
함수의 base64 출력을 정수로 다시 변환하는 방법은 무엇입니까?
detly

16

재귀

나는 것이다 단순화 대부분의 투표 대답 에를 :

BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(n, b): 
    return "0" if not n else to_base(n//b, b).lstrip("0") + BS[n%b]

RuntimeError: maximum recursion depth exceeded in cmp매우 큰 정수와 음수에 대해 동일한 조언을 제공 합니다. (당신은 사용할 수 있습니다sys.setrecursionlimit(new_limit) )

반복적 인

하려면 재귀 문제를 방지 :

BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(s, b):
    res = ""
    while s:
        res+=BS[s%b]
        s//= b
    return res[::-1] or "0"

2
라이브러리없이 아름답게 리팩토링되었습니다.
Giampaolo Ferradini

정지 조건이되어야 return BS[0] if not n합니까? 그냥 당신 이처럼 멋진 숫자를 사용하려는 경우 :)
Arnaud P

@ArnaudP가 동의했습니다. 이것은 나를 위해 작동합니다 :return BS[n] if n < b else to_base(n // b) + BN[n % b]
Jens

15

파이썬에는 임의의 기준으로 정수를 인쇄하는 내장 함수가 없습니다. 원한다면 직접 작성해야합니다.


13

baseconv.py내 프로젝트에서 사용할 수 있습니다 : https://github.com/semente/python-baseconv

샘플 사용법 :

>>> 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'

이 예를 들어 같은 일부 bultin 컨버터이다 baseconv.base2, baseconv.base16하고 baseconv.base64.


12

>>> numpy.base_repr(10, base=3) '101'


좋은 해결책. 필자의 경우 clac로딩 시간 문제로 인해 많은 문제 가 발생하지 않았습니다 . numpy를 미리로드하면 clac에서 간단한 표현식 평가의 런타임이 3 배 이상 늘어납니다. 예 : clac 1+1 약 40ms에서 140ms로 증가했습니다.
Mark Borgerding 2018 년

1
참고 numpy.base_repr()그베이스 (36)의 같은 한계를 갖는다. 그렇지 않으면 ValueError
sbdchd

내장 된 "int"함수의 제한과 일치합니다. 더 큰베이스는 글자가 다
떨어지면

4

http://code.activestate.com/recipes/65212/

def base10toN(num,n):
    """Change a  to a base-n number.
    Up to base-36 is supported without special notation."""
    num_rep={10:'a',
         11:'b',
         12:'c',
         13:'d',
         14:'e',
         15:'f',
         16:'g',
         17:'h',
         18:'i',
         19:'j',
         20:'k',
         21:'l',
         22:'m',
         23:'n',
         24:'o',
         25:'p',
         26:'q',
         27:'r',
         28:'s',
         29:'t',
         30:'u',
         31:'v',
         32:'w',
         33:'x',
         34:'y',
         35:'z'}
    new_num_string=''
    current=num
    while current!=0:
        remainder=current%n
        if 36>remainder>9:
            remainder_string=num_rep[remainder]
        elif remainder>=36:
            remainder_string='('+str(remainder)+')'
        else:
            remainder_string=str(remainder)
        new_num_string=remainder_string+new_num_string
        current=current/n
    return new_num_string

동일한 링크에서 다른 것이 있습니다

def baseconvert(n, base):
    """convert positive decimal integer n to equivalent in another base (2-36)"""

    digits = "0123456789abcdefghijklmnopqrstuvwxyz"

    try:
        n = int(n)
        base = int(base)
    except:
        return ""

    if n < 0 or base < 2 or base > 36:
        return ""

    s = ""
    while 1:
        r = n % base
        s = digits[r] + s
        n = n / base
        if n == 0:
            break

    return s

base10toN은 num == 0 인 경우를 설명하지 않습니다.
Craeft

3

나는 이것을 위해 pip 패키지를 만들었습니다.

bases.js 에서 영감을 얻은 bases.py https://github.com/kamijoutouma/bases.py 를 사용하는 것이 좋습니다.

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

https://github.com/kamijoutouma/bases.py#known-basesalphabets참조하십시오 사용 가능한 염기는 를

편집 : 핍 링크 https://pypi.python.org/pypi/bases.py/0.2.2


이것은 알려진 기지에 대한 매력처럼 작동 합니다 .
Agi Hammerthief

이것은 지금까지 가장 좋은 대답입니다! 핍 포장에 감사드립니다!
ɹɐʎɯɐʞ

3
def base(decimal ,base) :
    list = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    other_base = ""
    while decimal != 0 :
        other_base = list[decimal % base] + other_base
        decimal    = decimal / base
    if other_base == "":
        other_base = "0"
    return other_base

print base(31 ,16)

산출:

"1F"


other-base와 동일 other - base하므로 다음을 사용해야합니다other_base
mbomb007

또한 decimal0 이면 올바르게 작동하지 않습니다 .
mbomb007

1
>>> import string
>>> def int2base(integer, base):
        if not integer: return '0'
        sign = 1 if integer > 0 else -1
        alphanum = string.digits + string.ascii_lowercase
        nums = alphanum[:base]
        res = ''
        integer *= sign
        while integer:
                integer, mod = divmod(integer, base)
                res += nums[mod]
        return ('' if sign == 1 else '-') + res[::-1]


>>> int2base(-15645, 23)
'-16d5'
>>> int2base(213, 21)
'a3'

1

관심있는 사람들을위한 재귀 솔루션. 물론 음의 이진 값에는 작동하지 않습니다. Two 's Complement를 구현해야합니다.

def generateBase36Alphabet():
    return ''.join([str(i) for i in range(10)]+[chr(i+65) for i in range(26)])

def generateAlphabet(base):
    return generateBase36Alphabet()[:base]

def intToStr(n, base, alphabet):
    def toStr(n, base, alphabet):
        return alphabet[n] if n < base else toStr(n//base,base,alphabet) + alphabet[n%base]
    return ('-' if n < 0 else '') + toStr(abs(n), base, alphabet)

print('{} -> {}'.format(-31, intToStr(-31, 16, generateAlphabet(16)))) # -31 -> -1F

1
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()

설명

어떤 기준에서든 모든 숫자는 a1+a2*base**2+a3*base**3..."임무"와 같습니다 .

모든 N=1,2,3...코드에서 슬라이스 aN*base**Na는 b=base**(N+1)모두 N보다 큰 b에 의해 "mouduling"을 분리하고 , func가 전류에 의해 호출 될 때마다 펑션이 감소 할 때마다 직렬 a가 N보다 작은 모든 a를 슬라이스합니다 aN*base**N.

Base = (base-1) == 1 때문에 base ** p % (base-1) == 1 그리고 q * base ^ p % (base-1) == q q = base-1 인 경우 한 가지 예외 만 0을 반환하는 경우 수정하려면 func이 확인하는 것이 시작부터 0입니다.


장점

이 샘플에는 (분할 대신) 단 하나의 곱셈과 상대적으로 적은 시간이 걸리는 일부 모류가 있습니다.


1
num = input("number")
power = 0
num = int(num)
while num > 10:
    num = num / 10
    power += 1

print(str(round(num, 2)) + "^" + str(power))

당신이 특별한 init을했던 간단한 정보를 추가하십시오
Farhana

이것은 저자의 질문에 대답 할 수 있지만, 설명 할 단어 및 / 또는 문서 링크가 부족합니다. 원시 코드 스 니펫은 주변에 문구가 없으면별로 도움이되지 않습니다. 좋은 답변을 작성하는 방법이 매우 도움 이 될 수도 있습니다. 답을 수정하십시오.
hellow

1
def base_changer(number,base):
    buff=97+abs(base-10)
    dic={};buff2='';buff3=10
    for i in range(97,buff+1):
        dic[buff3]=chr(i)
        buff3+=1   
    while(number>=base):
        mod=int(number%base)
        number=int(number//base)
        if (mod) in dic.keys():
            buff2+=dic[mod]
            continue
        buff2+=str(mod)
    if (number) in dic.keys():
        buff2+=dic[number]
    else:
        buff2+=str(number)

    return buff2[::-1]   

이 기능을 사용하면 십진수를 원하는 기본으로 쉽게 변환 할 수 있습니다.
montaqami

당신은 당신의 자신의 답변을 언급 할 필요가 없습니다, 당신은 설명을 추가하기 위해 편집 할 수 있습니다.
Pochmurnik

1

다음은 여러베이스를 다른베이스로 변환하는 방법의 예입니다.

from collections import namedtuple

Test = namedtuple("Test", ["n", "from_base", "to_base", "expected"])


def convert(n: int, from_base: int, to_base: int) -> int:
    digits = []
    while n:
        (n, r) = divmod(n, to_base)
        digits.append(r)    
    return sum(from_base ** i * v for i, v in enumerate(digits))


if __name__ == "__main__":
    tests = [
        Test(32, 16, 10, 50),
        Test(32, 20, 10, 62),
        Test(1010, 2, 10, 10),
        Test(8, 10, 8, 10),
        Test(150, 100, 1000, 150),
        Test(1500, 100, 10, 1050000),
    ]

    for test in tests:
        result = convert(*test[:-1])
        assert result == test.expected, f"{test=}, {result=}"
    print("PASSED!!!")

0
def dec_to_radix(input, to_radix=2, power=None):
    if not isinstance(input, int):
        raise TypeError('Not an integer!')
    elif power is None:
        power = 1

    if input == 0:
        return 0
    else:
        remainder = input % to_radix**power
        digit = str(int(remainder/to_radix**(power-1)))
        return int(str(dec_to_radix(input-remainder, to_radix, power+1)) + digit)

def radix_to_dec(input, from_radix):
    if not isinstance(input, int):
        raise TypeError('Not an integer!')
    return sum(int(digit)*(from_radix**power) for power, digit in enumerate(str(input)[::-1]))

def radix_to_radix(input, from_radix=10, to_radix=2, power=None):
    dec = radix_to_dec(input, from_radix)
    return dec_to_radix(dec, to_radix, power)

0

또 다른 짧은 것 (그리고 이해하기 쉬운) :

def int_to_str(n, b, symbols='0123456789abcdefghijklmnopqrstuvwxyz'):
    return (int_to_str(n/b, b, symbols) if n >= b else "") + symbols[n%b]

적절한 예외 처리 :

def int_to_str(n, b, symbols='0123456789abcdefghijklmnopqrstuvwxyz'):
    try:
        return (int_to_str(n/b, b) if n >= b else "") + symbols[n%b]
    except IndexError:
        raise ValueError(
            "The symbols provided are not enough to represent this number in "
            "this base")

0

베이스 2에서 10까지 작동하는 다른 솔루션은 더 높은베이스를 수정해야합니다.

def n2b(n, b):
    if n == 0:
        return 0
    d = []
    while n:
        d.append(int(n % b))
        n /= b
    return ''.join(map(str,d[::-1]))

예:

n2b(10,2) => '10100'
int(n2b(10,2),2) => 10

0

다음은 부호있는 정수 및 사용자 정의 숫자를 처리하는 재귀 버전입니다.

import string

def base_convert(x, base, digits=None):
    """Convert integer `x` from base 10 to base `base` using `digits` characters as digits.
    If `digits` is omitted, it will use decimal digits + lowercase letters + uppercase letters.
    """
    digits = digits or (string.digits + string.ascii_letters)
    assert 2 <= base <= len(digits), "Unsupported base: {}".format(base)
    if x == 0:
        return digits[0]
    sign = '-' if x < 0 else ''
    x = abs(x)
    first_digits = base_convert(x // base, base, digits).lstrip(digits[0])
    return sign + first_digits + digits[x % base]

0

문자열은 숫자를 나타내는 유일한 선택은 아닙니다. 정수 목록을 사용하여 각 숫자의 순서를 나타낼 수 있습니다. 그것들은 쉽게 문자열로 변환 될 수 있습니다.

어떤 답도 base <2를 거부하지 않습니다. 대부분이 매우 느리게 실행하거나 스택에 대한 오버 플로우와 충돌합니다 매우 큰 수 (** 43210와 같은 56789). 이러한 실패를 피하려면 다음과 같이 빠르게 줄이십시오.

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_basestr많은 수 (내 컴퓨터에서 약 0.3 초)와 비교할 수 있지만hex 하면 내 기계에서 약 0.3ms 또는 1000 배 빠릅니다. 그 이유는 큰 정수가 기본 256 (바이트)의 메모리에 저장되기 때문입니다. 각 바이트는 단순히 2 문자 16 진 문자열로 변환 될 수 있습니다. 이 정렬은 2의 거듭 제곱 인 염기에 대해서만 발생하므로 2, 8 및 16 (및 base64, ascii, utf16, utf32)에 대한 특별한 경우가 있습니다.

십진 문자열의 마지막 숫자를 고려하십시오. 정수를 형성하는 바이트 시퀀스와 어떤 관련이 있습니까? 하자가 바이트 라벨 s[i]과 함께 s[0]최하위 (리틀 엔디안)되고 있습니다. 그런 다음 마지막 숫자는 sum([s[i]*(256**i) % 10 for i in range(n)])입니다. 256 ** i는 i> 0 (6 * 6 = 36)에 대해 6으로 끝나므로 마지막 숫자는 (s[0]*5 + sum(s)*6)%10입니다. 이것으로부터, 마지막 숫자는 모든 바이트의 합에 의존한다는 것을 알 수 있습니다. 이 비 로컬 속성은 10 진수로의 변환을 어렵게 만듭니다.


0
def baseConverter(x, b):
    s = ""
    d = string.printable.upper()
    while x > 0:
        s += d[x%b]
        x = x / b
    return s[::-1]

python3의 경우 코드에서 수행하는 작업 : baseConverter (0, 26)-> ''baseConverter (1, 26)-> '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001'python2의 경우 baseConverter (0, 26)-> ''baseConverter (1, 26) -> 1 기본 변환기 (3, 26)-> 3 기본 변환기 (5, 26)-> 5 기본 변환기 (26, 26)-> 10 기본 변환기 (32, 26)-> 16
Drachenfels

0

저는 개인적으로이 기능을 사용합니다.

import string

def to_base(value, base, digits=string.digits+string.ascii_letters):    # converts decimal to base n

    digits_slice = digits[0:base]

    temporary_var = value
    data = [temporary_var]

    while True:
        temporary_var = temporary_var // base
        data.append(temporary_var)
        if temporary_var < base:
            break

    result = ''
    for each_data in data:
        result += digits_slice[each_data % base]
    result = result[::-1]

    return result

이것이 당신이 그것을 사용할 수있는 방법입니다

print(to_base(7, base=2))

산출: "111"

print(to_base(23, base=3))

산출: "212"

내 코드 개선을 제안하십시오.


0
def base_conversion(num, base):
    digits = []
    while num > 0:
        num, remainder = divmod(num, base)
        digits.append(remainder)
    return digits[::-1]

0

이것은 오래된 질문이지만 다른 답변 (2에서 36까지의 기초에 적합 함)이 다소 간단하다고 생각하여 받아 들일 것이라고 생각했습니다.

def intStr(n,base=10):
    if n < 0   : return "-" + intStr(-n,base)         # handle negatives
    if n < base: return chr([48,55][n>9] + n)         # 48 => "0"..., 65 => "A"...
    return intStr(n//base,base) + intStr(n%base,base) # recurse for multiple digits

-1

여기에 플로트 변환기가 없습니다. 그리고 나는 항상 세 자리로 그룹화를 놓쳤다.

할 것:

과학적인 표현에 - 민수기 (n.nnnnnn*10**(exp)- (가) '10'입니다self.baseDigits[1::-1]/self.to_string(len (self.baseDigits))

-from_string-function.

-base 1-> 로마 숫자?

agles와 복잡한 repr

그래서 여기 내 해결책이 있습니다 :

DIGITS = "0123456789abcdefghijklmnopqrstuvwxyz"


# note that the order of the digits is reversed for digits before the point
NO_GROUPING = lambda g: g

concat = "".join
concat_backwards = lambda g: concat(e for e in reversed(list(g)))

def grouping(length = 3, char = '_'):
    def yieldor(digits):
        i = 0
        for d in digits:
            if i == length:
                yield char
                i = 0
            yield d
            i+=1

    return yieldor

class Converter:
    def __init__(self, baseDigits: (int, str), beforePoint = NO_GROUPING, afterPoint = NO_GROUPING, decimalPoint = '.', digitPrecision = 16, trimZeros = True):
        if isinstance(baseDigits, int):
            baseDigits = DIGITS[:baseDigits]
        self.baseDigits = baseDigits

        self.beforePoint = beforePoint
        self.afterPoint  = afterPoint

        self.decimalPoint = decimalPoint
        self.digitPrecision = digitPrecision
        self.trimZeros = trimZeros

    def to_string(self, number: (int, float, complex)) -> str:
        if isinstance(number, complex):
            if number.imag == 0:
                return self.to_string(number.real)
            if number.real == 0:
                return self.to_string(number.imag) + 'j'
            return "({}+{}j)".format(self.to_string(number.real), self.to_string (number.imag))
        if number < 0:
            return '-' + self.to_string(-number)
        digitCount = len(self.baseDigits)
        if isinstance(number, float):
            # round correctly
            precError=digitCount**-self.digitPrecision
            number+=0.5*precError
            if self.trimZeros:
                def yieldor(n):
                    p = precError
                    for i in range(self.digitPrecision):
                        if n <= p:
                            return
                        p *= digitCount
                        n *= digitCount
                        digit = int(n)
                        n -= digit
                        yield self.baseDigits[digit]
            else:
                def yieldor(n):
                    for i in range(self.digitPrecision):
                        n *= digitCount
                        digit = int(n)
                        n -= digit
                        yield self.baseDigits[digit]

            a = concat(self.afterPoint(yieldor(number%1)))

            return (
                self.to_string(int(number)) + (a and self.decimalPoint + a)
            )

        else: #is int
            if not number: return self.baseDigits[0]
            def yieldor(n):
                while n:
                    n, digit = divmod(n, digitCount)
                    yield self.baseDigits[digit]
            return concat_backwards(self.beforePoint(yieldor(number)))

# some tests:
if __name__ == "__main__":
    def conv_test(num, digits, *argv, **kwv):
        print(num, "->", digits if isinstance(digits, int) else "{} ({})".format(len(digits), digits), Converter(digits, *argv, **kwv).to_string(num))
    conv_test(True, "ft")
    conv_test(123, 12, grouping(2))
    conv_test(-0xf00d, 16)
    conv_test(1000, True<<True, grouping(4))
    conv_test(1_000_000, "0+-", beforePoint = grouping(2, '|'))
    conv_test(1.5, 10)
    conv_test(0.999999999, 10, digitPrecision = 8)
    conv_test(-0.1, 10)

    import math
    conv_test(math.pi, 10, afterPoint = grouping(5, ' '))
    conv_test(0.123456789, 10, digitPrecision = 6)

    grSpc = grouping(1, ' ')
    conv_test(math.e, ["off", "on"], grSpc, grSpc, " dot ", digitPrecision = 7)

    conv_test(1 + 1.5j, 10)

    conv_test(50j, 10)

    conv_test(10.01, '-<>')

    # and generate some brainfuck-code here:
    conv_test(1701**42, '+-<>,.][', digitPrecision = 32)

-2
def bn(x,b,ab="0123456789abcdefghijklmnopqrstuvwxyz..."
    a = ""
    while (x>0):
        x,r = divmod(x,n)
        a += ab[r]
    return a[::-1]

bn(2**100, 36)

산출:

3ewfdnca0n6ld1ggvfgg

어떤 기본으로 변환하려면 역도 쉽습니다.


를 얻었다 NameError: global name 'n' is not defined. 되어 divmod(x, n)있어야하는데 divmod(x, b)?
wjandrea
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.