Python permet de créer facilement un entier à partir d'une chaîne d'une base donnée via
int(str, base).
Je veux effectuer l'inverse: création d'une chaîne à partir d'un entier , c'est-à-dire que je veux une fonction int2base(num, base)
, telle que:
int(int2base(x, b), b) == x
L'ordre du nom / argument de la fonction est sans importance.
Pour tout nombre x
et base b
qui int()
accepteront.
C'est une fonction facile à écrire: en fait c'est plus facile que de la décrire dans cette question. Cependant, je sens que je dois manquer quelque chose.
Je sais que sur les fonctions bin
, oct
, hex
, mais je ne peux pas les utiliser pour quelques raisons:
Ces fonctions ne sont pas disponibles sur les anciennes versions de Python, avec lesquelles j'ai besoin de compatibilité avec (2.2)
Je veux une solution générale qui peut être appelée de la même manière pour différentes bases
Je veux autoriser des bases autres que 2, 8, 16
Réponses:
Si vous avez besoin de compatibilité avec les anciennes versions de Python, vous pouvez soit utiliser gmpy (qui inclut une fonction de conversion int-to-string rapide et complètement générale, et peut être construit pour ces anciennes versions - vous devrez peut-être essayer des versions plus anciennes depuis les versions récentes n'ont pas été testées pour les versions vénérables de Python et GMP, seulement des versions quelque peu récentes), ou, pour moins de vitesse mais pour plus de commodité, utiliser du code Python - par exemple, le plus simplement:
la source
gmpy2.digits(x, base)
.digs = string.digits + string.lowercase + string.uppercase
string.digits + string.letters
)x //= base
ce qui se comporte comme/=
dans Python 2 en supprimant la décimale. Cette réponse devrait inclure un avertissement que c'est pour Python 2.Étonnamment, les gens ne donnaient que des solutions qui se convertissaient en petites bases (plus petites que la longueur de l'alphabet anglais). Il n'y avait aucune tentative de donner une solution qui se transforme en n'importe quelle base arbitraire de 2 à l'infini.
Voici donc une solution super simple:
donc si vous avez besoin de convertir un très grand nombre en base
577
,numberToBase(67854 ** 15 - 102, 577)
, Vous donnera une bonne solution:[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 vous pourrez ensuite convertir en n'importe quelle base de votre choix
la source
int(4545,16)
donné "11c1" et aint(4545,60)
donné "1:15:45". Ainsi, la fonction remplit trois fonctions: la conversion aux formats décimal, informatique et d'horodatage.digits
?réf: http://code.activestate.com/recipes/65212/
Veuillez noter que cela peut entraîner
pour les très grands entiers.
la source
len(numerals)
, et (b)num % b
est, par chance, <len(numerals)
. Par exemple, bien que lanumerals
chaîne ne comporte que 36 caractères, baseN (60, 40) renvoie'1k'
tandis que baseN (79, 40) lève unIndexError
. Les deux devraient soulever une sorte d'erreur. Le code doit être révisé pour générer une erreur sinot 2 <= base <= len(numerals)
.b
cela ne dépasserait certainement paslen(numerals)
, eh bien, bonne chance à vous.return numerals[0] if num == 0 else baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b]
est tout aussi brève.la source
0
inutile. Voici la documentation de Python 2: docs.python.org/2/library/string.html#format-string-syntaxhex(100)[2:]
,oct(100)[2:]
etbin(100)[2:]
.Excellentes réponses! Je suppose que la réponse à ma question était "non". Je ne manquais pas de solution évidente. Voici la fonction que j'utiliserai qui condense les bonnes idées exprimées dans les réponses.
la source
Récursif
Je simplifierais la réponse la plus votée à:
Avec le même conseil pour
RuntimeError: maximum recursion depth exceeded in cmp
les très grands nombres entiers et les nombres négatifs. (Vous pourriez utilisersys.setrecursionlimit(new_limit)
)Itératif
Pour éviter les problèmes de récursivité :
la source
return BS[0] if not n
alors? Juste au cas où vous voudriez utiliser des chiffres fantaisistes, comme moi :)return BS[n] if n < b else to_base(n // b) + BN[n % b]
Python n'a pas de fonction intégrée pour imprimer un entier dans une base arbitraire. Vous devrez écrire le vôtre si vous le souhaitez.
la source
Vous pouvez utiliser à
baseconv.py
partir de mon projet: https://github.com/semente/python-baseconvExemple d'utilisation:
Il existe des convertisseurs bultin comme par exemple
baseconv.base2
,baseconv.base16
etbaseconv.base64
.la source
>>> numpy.base_repr(10, base=3) '101'
la source
clac
pour des soucis de temps de chargement. Le préchargement de numpy fait plus que tripler le temps d'exécution de l'évaluation d'une expression simple dans clac: par exemple, ilclac 1+1
est passé d'environ 40 ms à 140 ms.numpy.base_repr()
a une limite de 36 comme base. Sinon, il jette unValueError
http://code.activestate.com/recipes/65212/
Voici un autre à partir du même lien
la source
J'ai fait un paquet pip pour ça.
Je vous recommande d'utiliser mon bases.py https://github.com/kamijoutouma/bases.py qui a été inspiré par bases.js
reportez-vous à https://github.com/kamijoutouma/bases.py#known-basesalphabets pour connaître les bases utilisables
EDIT: lien pip https://pypi.python.org/pypi/bases.py/0.2.2
la source
production:
la source
other-base
est le même queother - base
, vous devez donc utiliserother_base
decimal
est égal à zéro.la source
Une solution récursive pour les personnes intéressées. Bien sûr, cela ne fonctionnera pas avec des valeurs binaires négatives. Vous devez implémenter Two's Complement.
la source
explication
Dans n'importe quelle base, chaque nombre est égal à
a1+a2*base**2+a3*base**3...
La «mission» est de trouver tous les a.Pour tout
N=1,2,3...
le code isole leaN*base**N
par «mouduling» par b pourb=base**(N+1)
lequel tranche tous les a plus gros que N, et tranche tous les a que leur série est plus petite que N en diminuant a chaque fois que la fonction est appelée par le courantaN*base**N
.Base% (base-1) == 1 à cet effet base ** p% (base-1) == 1 et donc q * base ^ p% (base-1) == q avec une seule exception lorsque q = base-1 qui renvoie 0. Pour corriger cela au cas où il retourne 0, le func vérifie qu'il est 0 depuis le début.
avantages
dans cet échantillon, il n'y a qu'une seule multiplication (au lieu de la division) et quelques moudulues qui prennent relativement peu de temps.
la source
la source
la source
Voici un exemple de conversion d'un certain nombre de bases en une autre base.
la source
la source
Un autre court (et plus facile à comprendre imo):
Et avec une gestion des exceptions appropriée:
la source
Une autre solution, fonctionne avec la base 2 à 10, doit être modifiée pour les bases supérieures:
Exemple:
la source
Voici une version récursive qui gère les entiers signés et les chiffres personnalisés.
la source
Les chaînes ne sont pas le seul choix pour représenter les nombres: vous pouvez utiliser une liste d'entiers pour représenter l'ordre de chaque chiffre. Ceux-ci peuvent facilement être convertis en chaîne.
Aucune des réponses ne rejette la base <2; et la plupart s'exécuteront très lentement ou planteront avec des débordements de pile pour de très grands nombres (comme 56789 ** 43210). Pour éviter de tels échecs, réduisez rapidement comme ceci:
Speedwise,
n_to_base
est comparable àstr
pour les grands nombres (environ 0,3 s sur ma machine), mais si vous comparez contrehex
vous pourriez être surpris (environ 0,3 ms sur ma machine, ou 1000 fois plus rapide). La raison en est que le grand entier est stocké en mémoire dans la base 256 (octets). Chaque octet peut simplement être converti en une chaîne hexadécimale à deux caractères. Cet alignement ne se produit que pour les bases qui sont des puissances de deux, c'est pourquoi il existe des cas spéciaux pour 2,8 et 16 (et base64, ascii, utf16, utf32).Considérez le dernier chiffre d'une chaîne décimale. Comment est-il lié à la séquence d'octets qui forme son entier? Étiquetons les octets
s[i]
commes[0]
étant les moins significatifs (petit endian). Ensuite, le dernier chiffre estsum([s[i]*(256**i) % 10 for i in range(n)])
. Eh bien, il arrive que 256 ** i se termine par un 6 pour i> 0 (6 * 6 = 36) de sorte que le dernier chiffre soit(s[0]*5 + sum(s)*6)%10
. De là, vous pouvez voir que le dernier chiffre dépend de la somme de tous les octets. Cette propriété non locale rend la conversion en décimales plus difficile.la source
la source
Eh bien, j'utilise personnellement cette fonction, écrite par moi
Voilà comment vous pouvez l'utiliser
print(to_base(7, base=2))
Production:
"111"
print(to_base(23, base=3))
Production:
"212"
N'hésitez pas à suggérer des améliorations à mon code.
la source
la source
C'est une vieille question mais j'ai pensé partager mon point de vue car je pense que c'est un peu plus simple que les autres réponses (bon pour les bases de 2 à 36):
la source
Je n'ai vu aucun convertisseur de flotteur ici. Et j'ai raté le regroupement pour toujours trois chiffres.
FAIRE:
-Nombre expression scientifique
(n.nnnnnn*10**(exp)
- l''10'
estself.baseDigits[1::-1]/self.to_string(len (self.baseDigits))
-de-fonction-chaîne.
-base 1 -> nombres romains?
-repr de complexe avec agles
Voici donc ma solution:
la source
production:
pour convertir en n'importe quelle base, l'inverse est aussi facile.
la source
NameError: global name 'n' is not defined
. Estdivmod(x, n)
censé l'êtredivmod(x, b)
?