Convert.ToString
se puede utilizar para convertir un número en su representación de cadena equivalente en una base específica.
Ejemplo:
string binary = Convert.ToString(5, 2); // convert 5 to its binary representation
Console.WriteLine(binary); // prints 101
Sin embargo, como se señala en los comentarios, Convert.ToString
solo admite el siguiente conjunto de bases limitado, pero generalmente suficiente: 2, 8, 10 o 16.
Actualización (para cumplir con el requisito de convertir a cualquier base):
No conozco ningún método en el BCL que sea capaz de convertir números a cualquier base, por lo que tendría que escribir su propia función de utilidad pequeña. Una muestra simple se vería así (tenga en cuenta que esto seguramente se puede hacer más rápido reemplazando la concatenación de cadenas):
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);
}
}
Actualización 2 (mejora del rendimiento)
El uso de un búfer de matriz en lugar de la concatenación de cadenas para construir la cadena de resultado proporciona una mejora del rendimiento, especialmente en números grandes (ver método IntToStringFast
). En el mejor de los casos (es decir, la entrada más larga posible), este método es aproximadamente tres veces más rápido. Sin embargo, para números de 1 dígito (es decir, 1 dígito en la base de destino), IntToString
será más rápido.
Recientemente escribí en un blog sobre esto . Mi implementación no utiliza ninguna operación de cadena durante los cálculos, lo que lo hace muy rápido . Se admite la conversión a cualquier sistema numérico con base de 2 a 36:
También he implementado una función inversa rápida en caso de que alguien la necesite también: sistema numérico arbitrario a decimal .
fuente
result = "-" + result
? ¿Es eso algún tipo de relleno? ¿Cómo podría modificar el código para que solo use AZ o 0-9 para un carácter de relleno?"-"
enresult = "-" + result
representa el signo negativo de los números negativos. No es un carácter de relleno.MÉTODOS RÁPIDOS " DE " Y " A "
Llego tarde a la fiesta, pero combiné las respuestas anteriores y las mejoré. Creo que estos dos métodos son más rápidos que cualquier otro publicado hasta ahora. Pude convertir 1,000,000 de números desde y hacia la base 36 en menos de 400ms en una máquina de un solo núcleo.
El siguiente ejemplo es para la base 62 . Cambie la
BaseChars
matriz para convertir desde y hacia cualquier otra base.EDITAR (2018-07-12)
Se corrigió para abordar el caso de esquina encontrado por @AdrianBotor (ver comentarios) convirtiendo 46655 a base 36. Esto es causado por un pequeño error de punto flotante al calcular
Math.Log(46656, 36)
cuál es exactamente 3, pero .NET regresa3 + 4.44e-16
, lo que causa un carácter adicional en el búfer de salida .fuente
BaseToLong(LongToBase(46655)) == 46655
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
y convierta el valor46655
. El resultado debería ser,ZZZ
pero en el depurador obtengo\0ZZZ
. Solo este valor se vuelve adicional\0
. Por ejemplo, el valor se46654
convierte correctamente enZZY
.LongToBase
areturn new string(buffer, (int) i, buffer.Length - (int)i);
También se puede usar una versión ligeramente modificada de la aceptada y ajustar la cadena de caracteres base a sus necesidades:
fuente
Muy tarde para la fiesta en este caso, pero recientemente escribí la siguiente clase de ayuda para un proyecto en el trabajo. Fue diseñado para convertir cadenas cortas en números y viceversa (una función de hash perfecta simplista ), sin embargo, también realizará la conversión de números entre bases arbitrarias. La
Base10ToString
implementación del método responde a la pregunta que se publicó originalmente.La
shouldSupportRoundTripping
bandera que se pasa al constructor de la clase es necesaria para evitar la pérdida de los dígitos iniciales de la cadena numérica durante la conversión a base 10 y viceversa (¡crucial, dados mis requisitos!). La mayoría de las veces, la pérdida de ceros iniciales de la cadena de números probablemente no será un problema.De todos modos, aquí está el código:
Esto también se puede subclasificar para derivar convertidores de números personalizados:
Y el código se usaría así:
fuente
¿Podría ayudarte esta clase de esta publicación en el foro ?
Totalmente no probado ... ¡avísame si funciona! (Copie y pegue en caso de que la publicación del foro desaparezca o algo así ...)
fuente
Yo también estaba buscando una forma rápida de convertir un número decimal a otra base en el rango de [2..36], así que desarrollé el siguiente código. Es simple de seguir y usa un objeto Stringbuilder como un proxy para un búfer de caracteres que podemos indexar carácter por carácter. El código parece ser muy rápido en comparación con las alternativas y mucho más rápido que inicializar caracteres individuales en una matriz de caracteres.
Para su propio uso, es posible que prefiera: 1 / Devolver una cadena en blanco en lugar de lanzar una excepción. 2 / elimine la comprobación de radix para que el método se ejecute aún más rápido 3 / Inicialice el objeto Stringbuilder con 32 '0's y elimine la línea result.Remove (0, i) ;. Esto hará que la cadena se devuelva con ceros a la izquierda y aumentará aún más la velocidad. 4 / Haga que el objeto Stringbuilder sea un campo estático dentro de la clase, de modo que no importa cuántas veces se llame al método DecimalToBase, el objeto Stringbuilder solo se inicializa una vez. Si hace este cambio 3 anterior ya no funcionaría.
Espero que alguien encuentre esto útil :)
AtomicParadox
fuente
Estaba usando esto para almacenar un Guid como una cadena más corta (pero estaba limitado a usar 106 caracteres). Si alguien está interesado, aquí está mi código para decodificar la cadena de nuevo a un valor numérico (en este caso usé 2 ulongs para el valor Guid, en lugar de codificar un Int128 (ya que estoy en 3.5, no 4.0). Para mayor claridad, CODE es un cadena constante con 106 caracteres únicos. ConvertLongsToBytes es bastante aburrido.
fuente
Tenía una necesidad similar, excepto que también necesitaba hacer matemáticas con los "números". Tomé algunas de las sugerencias aquí y creé una clase que hará todas estas cosas divertidas. Permite que se use cualquier carácter Unicode para representar un número y también funciona con decimales.
Esta clase es bastante fácil de usar. Simplemente cree un número como un tipo de
New BaseNumber
, configure algunas propiedades y listo. Las rutinas se encargan de cambiar entre la base 10 y la base x automáticamente y el valor que establece se conserva en la base en la que lo estableció, por lo que no se pierde precisión (hasta la conversión, es decir, pero incluso entonces la pérdida de precisión debería ser mínima ya que esto usos rutinariosDouble
yLong
siempre que sea posible).No puedo controlar la velocidad de esta rutina. Probablemente sea bastante lento, por lo que no estoy seguro de si se adaptará a las necesidades de quien hizo la pregunta, pero seguro que es flexible, así que espero que alguien más pueda usarlo.
Para cualquier otra persona que pueda necesitar este código para calcular la siguiente columna en Excel, incluiré el código de bucle que usé para aprovechar esta clase.
Y ahora para que el código recorra las columnas de Excel:
Notarás que la parte importante de la parte de Excel es que 0 se identifica con una @ en el número re-basado. Así que solo filtro todos los números que tienen una @ y obtengo la secuencia adecuada (A, B, C, ..., Z, AA, AB, AC, ...).
fuente
fuente
Si alguien está buscando una opción de VB, esto se basó en la respuesta de Pavel:
fuente
Esta es una forma bastante sencilla de hacer esto, pero puede que no sea la más rápida. Es bastante poderoso porque se puede componer.
Combine esto con este método de extensión simple y ahora es posible obtener cualquier base:
Se puede usar así:
La salida es:
fuente