Convert.ToString
peut être utilisé pour convertir un nombre en sa représentation sous forme de chaîne équivalente dans une base spécifiée.
Exemple:
string binary = Convert.ToString(5, 2); // convert 5 to its binary representation
Console.WriteLine(binary); // prints 101
Cependant, comme indiqué dans les commentaires, Convert.ToString
ne prend en charge que l'ensemble limité - mais généralement suffisant - de bases suivantes: 2, 8, 10 ou 16.
Mise à jour (pour répondre à l'exigence de conversion vers n'importe quelle base):
Je ne connais aucune méthode de la BCL capable de convertir des nombres en n'importe quelle base, vous devrez donc écrire votre propre petite fonction utilitaire. Un exemple simple ressemblerait à cela (notez que cela peut sûrement être rendu plus rapide en remplaçant la concaténation de chaînes):
class Program
{
static void Main(string[] args)
{
// convert to binary
string binary = IntToString(42, new char[] { '0', '1' });
// convert to hexadecimal
string hex = IntToString(42,
new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'});
// convert to hexavigesimal (base 26, A-Z)
string hexavigesimal = IntToString(42,
Enumerable.Range('A', 26).Select(x => (char)x).ToArray());
// convert to sexagesimal
string xx = IntToString(42,
new char[] { '0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x'});
}
public static string IntToString(int value, char[] baseChars)
{
string result = string.Empty;
int targetBase = baseChars.Length;
do
{
result = baseChars[value % targetBase] + result;
value = value / targetBase;
}
while (value > 0);
return result;
}
/// <summary>
/// An optimized method using an array as buffer instead of
/// string concatenation. This is faster for return values having
/// a length > 1.
/// </summary>
public static string IntToStringFast(int value, char[] baseChars)
{
// 32 is the worst cast buffer size for base 2 and int.MaxValue
int i = 32;
char[] buffer = new char[i];
int targetBase= baseChars.Length;
do
{
buffer[--i] = baseChars[value % targetBase];
value = value / targetBase;
}
while (value > 0);
char[] result = new char[32 - i];
Array.Copy(buffer, i, result, 0, 32 - i);
return new string(result);
}
}
Mise à jour 2 (amélioration des performances)
L'utilisation d'un tampon de tableau au lieu de la concaténation de chaînes pour construire la chaîne de résultat améliore les performances, en particulier sur un grand nombre (voir méthode IntToStringFast
). Dans le meilleur des cas (c'est-à-dire la saisie la plus longue possible), cette méthode est environ trois fois plus rapide. Cependant, pour les nombres à 1 chiffre (c'est-à-dire 1 chiffre dans la base cible), IntToString
sera plus rapide.
J'ai récemment blogué à ce sujet . Mon implémentation n'utilise aucune opération de chaîne lors des calculs, ce qui la rend très rapide . La conversion vers n'importe quel système numérique avec une base de 2 à 36 est prise en charge:
J'ai également implémenté une fonction inverse rapide au cas où quelqu'un en aurait besoin aussi: Arbitrary to Decimal Numeral System .
la source
result = "-" + result
? Est-ce une sorte de rembourrage? Comment pourrais-je modifier le code pour n'utiliser que AZ ou 0-9 pour un caractère de remplissage?"-"
inresult = "-" + result
représente le signe négatif des nombres négatifs. Ce n'est pas un caractère de remplissage.MÉTHODES RAPIDES " DE " ET " À "
Je suis en retard à la fête, mais j'ai composé les réponses précédentes et les ai améliorées. Je pense que ces deux méthodes sont plus rapides que toutes les autres publiées jusqu'à présent. J'ai pu convertir 1 000 000 de numéros de et vers la base 36 en moins de 400 ms dans une machine à un seul cœur.
L'exemple ci-dessous concerne la base 62 . Modifiez le
BaseChars
tableau à convertir depuis et vers n'importe quelle autre base.MODIFIER (2018-07-12)
Correction pour résoudre le cas d'angle trouvé par @AdrianBotor (voir les commentaires) convertissant 46655 en base 36. Cela est causé par une petite erreur de calcul en virgule flottante
Math.Log(46656, 36)
qui est exactement 3, mais .NET retourne3 + 4.44e-16
, ce qui provoque un caractère supplémentaire dans le tampon de sortie .la source
BaseToLong(LongToBase(46655)) == 46655
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
et convertissons la valeur46655
. Le résultat devrait êtreZZZ
mais dans le débogueur je reçois\0ZZZ
. Seule cette valeur est supplémentaire\0
. Par exemple, la valeur se46654
convertit correctement enZZY
.LongToBase
àreturn new string(buffer, (int) i, buffer.Length - (int)i);
On peut également utiliser une version légèrement modifiée de celle acceptée et ajuster la chaîne de caractères de base en fonction de ses besoins:
la source
Très tard à la fête sur celui-ci, mais j'ai récemment écrit la classe d'aide suivante pour un projet au travail. Il a été conçu pour convertir des chaînes courtes en nombres et inversement (une fonction de hachage parfaite simpliste ), mais il effectuera également une conversion de nombres entre des bases arbitraires. le
Base10ToString
implémentation de la méthode répond à la question qui a été initialement publiée.le
shouldSupportRoundTripping
drapeau passé au constructeur de classe est nécessaire pour éviter la perte des chiffres de tête de la chaîne numérique lors de la conversion en base 10 et inversement (crucial, compte tenu de mes exigences!). La plupart du temps, la perte des 0 en tête de la chaîne numérique ne sera probablement pas un problème.Bref, voici le code:
Cela peut également être sous-classé pour dériver des convertisseurs de nombres personnalisés:
Et le code serait utilisé comme ceci:
la source
Ce cours de ce post de forum pourrait-il vous aider?
Totalement non testé ... faites-moi savoir si cela fonctionne! (Copiez-le au cas où le message du forum disparaîtrait ou quelque chose du genre ...)
la source
Moi aussi, je cherchais un moyen rapide de convertir un nombre décimal en une autre base dans la plage de [2..36] alors j'ai développé le code suivant. C'est simple à suivre et utilise un objet Stringbuilder comme proxy pour un tampon de caractères que nous pouvons indexer caractère par caractère. Le code semble être très rapide par rapport aux alternatives et beaucoup plus rapide que l'initialisation de caractères individuels dans un tableau de caractères.
Pour votre propre usage, vous préférerez peut-être: 1 / Renvoyer une chaîne vide plutôt que de lever une exception. 2 / supprimer la vérification de base pour rendre la méthode encore plus rapide 3 / Initialiser l'objet Stringbuilder avec 32 '0 et supprimer le résultat de la ligne.Supprimer (0, i) ;. Cela entraînera le retour de la chaîne avec des zéros non significatifs et augmentera encore la vitesse. 4 / Faites de l'objet Stringbuilder un champ statique au sein de la classe afin que peu importe le nombre de fois que la méthode DecimalToBase est appelée l'objet Stringbuilder n'est initialisé qu'une seule fois. Si vous faites ce changement 3 ci-dessus ne fonctionnerait plus.
J'espère que quelqu'un trouvera cela utile :)
AtomicParadox
la source
J'utilisais ceci pour stocker un Guid sous forme de chaîne plus courte (mais était limité à 106 caractères). Si quelqu'un est intéressé, voici mon code pour décoder la chaîne en valeur numérique (dans ce cas, j'ai utilisé 2 ulongs pour la valeur Guid, plutôt que de coder un Int128 (puisque je suis en 3.5 et non en 4.0). Pour plus de clarté, CODE est un chaîne const avec 106 caractères uniques. ConvertLongsToBytes est assez peu passionnant.
la source
J'avais un besoin similaire, sauf que j'avais aussi besoin de faire des maths sur les «nombres». J'ai pris certaines des suggestions ici et j'ai créé une classe qui fera tout ce truc amusant. Il permet d'utiliser n'importe quel caractère Unicode pour représenter un nombre et fonctionne également avec des décimales.
Cette classe est assez facile à utiliser. Créez simplement un nombre en tant que type de
New BaseNumber
, définissez quelques propriétés et désactivez. Les routines prennent soin de basculer automatiquement entre la base 10 et la base x et la valeur que vous définissez est conservée dans la base dans laquelle vous la définissez, donc aucune précision n'est perdue (jusqu'à la conversion, mais même dans ce cas, la perte de précision devrait être très minime car cela utilisations courantesDouble
etLong
dans la mesure du possible).Je ne peux pas commander sur la vitesse de cette routine. C'est probablement assez lent, donc je ne sais pas si cela répondra aux besoins de celui qui a posé la question, mais il est certain qu'il est flexible, alors j'espère que quelqu'un d'autre pourra l'utiliser.
Pour toute autre personne pouvant avoir besoin de ce code pour calculer la colonne suivante dans Excel, j'inclurai le code de boucle que j'ai utilisé et qui exploite cette classe.
Et maintenant, pour que le code passe en boucle dans les colonnes Excel:
Vous noterez que la partie importante de la partie Excel est que 0 est identifié par un @ dans le nombre re-basé. Donc, je filtre simplement tous les nombres qui ont un @ en eux et j'obtiens la séquence appropriée (A, B, C, ..., Z, AA, AB, AC, ...).
la source
la source
Si quelqu'un cherche une option VB, cela était basé sur la réponse de Pavel:
la source
C'est une façon assez simple de le faire, mais ce n'est peut-être pas la plus rapide. Il est assez puissant car il est composable.
Combinez cela avec cette méthode d'extension simple et tout obtenir une base est maintenant possible:
Il peut être utilisé comme ceci:
La sortie est:
la source