O Python permite a fácil criação de um número inteiro a partir de uma sequência de uma determinada base via
int(str, base).
Eu quero executar o inverso: criação de uma string a partir de um número inteiro , ou seja, eu quero alguma função int2base(num, base)
, como:
int(int2base(x, b), b) == x
A ordem do nome / argumento da função não é importante.
Para qualquer número x
e base b
que int()
aceite.
Essa é uma função fácil de escrever: na verdade, é mais fácil do que descrevê-la nesta pergunta. No entanto, sinto que devo estar perdendo alguma coisa.
Eu sei sobre as funções bin
, oct
, hex
, mas não pode usá-los por algumas razões:
Essas funções não estão disponíveis em versões mais antigas do Python, com as quais eu preciso de compatibilidade com (2.2)
Eu quero uma solução geral que possa ser chamada da mesma maneira para bases diferentes
Quero permitir bases diferentes de 2, 8, 16
Respostas:
Se você precisar de compatibilidade com versões antigas do Python, poderá usar o gmpy (que inclui uma função de conversão int-to-string rápida e completamente geral e pode ser construído para essas versões antigas - você pode precisar tentar versões mais antigas, pois os mais recentes não foram testados para veneráveis lançamentos em Python e GMP, apenas um pouco recentes) ou, para menos velocidade, mas com mais comodidade, use o código Python - por exemplo, mais simplesmente:
fonte
gmpy2.digits(x, base)
.digs = string.digits + string.lowercase + string.uppercase
string.digits + string.letters
)x //= base
que se comporta como/=
no Python 2 ao largar o decimal. Esta resposta deve incluir um aviso de isenção de responsabilidade de que é para o Python 2. #Surpreendentemente, as pessoas estavam dando apenas soluções que se convertem em pequenas bases (menores que o comprimento do alfabeto inglês). Não houve tentativa de fornecer uma solução que se converta em qualquer base arbitrária de 2 para o infinito.
Então, aqui está uma solução super simples:
então, se você precisar converter um número super enorme para a base
577
,numberToBase(67854 ** 15 - 102, 577)
, Lhe dará uma solução correta:[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]
,Que você pode converter posteriormente para qualquer base que desejar
fonte
int(4545,16)
deu "11c1" eint(4545,60)
deu "1:15:45". Assim, a função triplicou: converter para formatos decimal, computadorizado e de carimbo de data / hora.digits
?ref: http://code.activestate.com/recipes/65212/
Esteja ciente de que isso pode levar a
para números inteiros muito grandes.
fonte
len(numerals)
e (b)num % b
é, por sorte, <len(numerals)
. por exemplo, embora anumerals
string tenha apenas 36 caracteres, a baseN (60, 40) retorna'1k'
enquanto a baseN (79, 40) gera umIndexError
. Ambos devem gerar algum tipo de erro. O código deve ser revisado para gerar um erro senot 2 <= base <= len(numerals)
.b
não excederialen(numerals)
, bem, boa sorte para você.return numerals[0] if num == 0 else baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b]
é tão breve.fonte
0
é desnecessário. Aqui está a documentação do Python 2: docs.python.org/2/library/string.html#format-string-syntaxhex(100)[2:]
,oct(100)[2:]
ebin(100)[2:]
.Ótimas respostas! Acho que a resposta para minha pergunta foi "não". Não estava faltando uma solução óbvia. Aqui está a função que usarei que condensa as boas idéias expressas nas respostas.
fonte
Recursivo
Eu iria simplificar a resposta mais votada para:
Com o mesmo conselho para
RuntimeError: maximum recursion depth exceeded in cmp
números inteiros muito grandes e números negativos. (Você poderia usarsys.setrecursionlimit(new_limit)
)Iterativo
Para evitar problemas de recursão :
fonte
return BS[0] if not n
então? Apenas no caso de você querer usar dígitos extravagantes, como eu faço :)return BS[n] if n < b else to_base(n // b) + BN[n % b]
O Python não possui uma função interna para imprimir um número inteiro em uma base arbitrária. Você terá que escrever o seu próprio, se quiser.
fonte
Você poderia usar
baseconv.py
do meu projeto: https://github.com/semente/python-baseconvUso da amostra:
Existem alguns conversores de bultina, como por exemplo
baseconv.base2
,baseconv.base16
ebaseconv.base64
.fonte
>>> numpy.base_repr(10, base=3) '101'
fonte
clac
devido a preocupações com o tempo de carregamento. O pré-carregamento do numpy mais do que triplica o tempo de execução da avaliação de expressões simples no clac: por exemplo,clac 1+1
passou de cerca de 40ms para 140ms.numpy.base_repr()
tem um limite de 36 como base. Caso contrário, ele lança umValueError
http://code.activestate.com/recipes/65212/
Aqui está outro do mesmo link
fonte
Eu fiz um pacote de pip para isso.
Eu recomendo que você use minhas bases.py https://github.com/kamijoutouma/bases.py, que foi inspirada em bases.js
consulte https://github.com/kamijoutouma/bases.py#known-basesalphabets para saber quais bases são utilizáveis
EDIT: link pip https://pypi.python.org/pypi/bases.py/0.2.2
fonte
resultado:
fonte
other-base
é o mesmo queother - base
, então você deve usar #other_base
decimal
for zero.fonte
Uma solução recursiva para os interessados. Obviamente, isso não funcionará com valores binários negativos. Você precisaria implementar o Complemento Dois.
fonte
explicação
Em qualquer base, todo número é igual a
a1+a2*base**2+a3*base**3...
"missão" é encontrar todos os a.Para cada
N=1,2,3...
código, oaN*base**N
"mouduling" é isolado por "b", parab=base**(N+1)
qual fatia todos a é maior que N e fatiga todos os "a" de que sua série é menor que N diminuindo a cada vez que a função é chamada pela correnteaN*base**N
.Base% (base-1) == 1 para a base ** p% (base-1) == 1 e, portanto, q * base ^ p% (base-1) == q com apenas uma exceção quando q = base-1 que retorna 0. Para corrigir que, no caso de retornar 0, a função está verificando se é 0 desde o início.
vantagens
nesta amostra, existem apenas uma multiplicação (em vez de divisão) e algumas mudas, que levam relativamente pouco tempo.
fonte
fonte
fonte
Aqui está um exemplo de como converter um número de qualquer base em outra base.
fonte
fonte
Outro pequeno (e mais fácil de entender):
E com manipulação de exceção adequada:
fonte
Outra solução, funciona com as bases 2 a 10, precisa ser modificada para bases mais altas:
Exemplo:
fonte
Aqui está uma versão recursiva que lida com números inteiros assinados e dígitos personalizados.
fonte
Strings não são a única opção para representar números: você pode usar uma lista de números inteiros para representar a ordem de cada dígito. Aqueles podem ser facilmente convertidos em uma string.
Nenhuma das respostas rejeita a base <2; e a maioria será executada muito lentamente ou travará com estouros de pilha para números muito grandes (como 56789 ** 43210). Para evitar essas falhas, reduza rapidamente assim:
Speedwise,
n_to_base
é comparávelstr
a números grandes (cerca de 0,3s na minha máquina), mas se você comparar comhex
você, poderá se surpreender (cerca de 0,3ms na minha máquina ou 1000x mais rápido). O motivo é porque o número inteiro grande é armazenado na memória na base 256 (bytes). Cada byte pode simplesmente ser convertido em uma sequência hexadecimal de dois caracteres. Esse alinhamento ocorre apenas para bases com potências de dois, e é por isso que existem casos especiais para 2,8 e 16 (e base64, ascii, utf16, utf32).Considere o último dígito de uma sequência decimal. Como isso se relaciona com a sequência de bytes que forma seu número inteiro? Vamos rotular os bytes
s[i]
comos[0]
sendo os menos significativos (little endian). Então o último dígito ésum([s[i]*(256**i) % 10 for i in range(n)])
. Bem, acontece que 256 ** i termina com um 6 para i> 0 (6 * 6 = 36), de modo que o último dígito é(s[0]*5 + sum(s)*6)%10
. A partir disso, você pode ver que o último dígito depende da soma de todos os bytes. Essa propriedade não-local é o que dificulta a conversão para decimal.fonte
fonte
Bem, eu pessoalmente uso essa função, escrita por mim
É assim que você pode usá-lo
print(to_base(7, base=2))
Resultado:
"111"
print(to_base(23, base=3))
Resultado:
"212"
Por favor, sinta-se livre para sugerir melhorias no meu código.
fonte
fonte
Esta é uma pergunta antiga, mas pensei em compartilhar minha opinião, pois acho que é um pouco mais simples que outras respostas (boas para bases de 2 a 36):
fonte
Eu não vi nenhum conversor de flutuador aqui. E eu perdi o agrupamento por sempre três dígitos.
FAÇAM:
-números na expressão científica
(n.nnnnnn*10**(exp)
-'10'
éself.baseDigits[1::-1]/self.to_string(len (self.baseDigits))
-from_string-function.
-base 1 -> números romanos?
-repr de complexo com agles
Então aqui está a minha solução:
fonte
resultado:
para converter para qualquer base, o inverso também é fácil.
fonte
NameError: global name 'n' is not defined
. Édivmod(x, n)
suposto serdivmod(x, b)
?