Convert.ToString
pode ser usado para converter um número em sua representação de string equivalente em uma base especificada.
Exemplo:
string binary = Convert.ToString(5, 2); // convert 5 to its binary representation
Console.WriteLine(binary); // prints 101
No entanto, como apontado pelos comentários, Convert.ToString
suporta apenas o seguinte conjunto limitado - mas normalmente suficiente - de bases: 2, 8, 10 ou 16.
Atualização (para atender ao requisito de conversão para qualquer base):
Não estou ciente de nenhum método no BCL que seja capaz de converter números em qualquer base, então você teria que escrever sua própria função de utilidade pequena. Um exemplo simples ficaria assim (observe que isso certamente pode ser feito mais rápido substituindo a concatenação de string):
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);
}
}
Atualização 2 (melhoria de desempenho)
Usar um buffer de array em vez de concatenação de string para construir a string de resultado fornece uma melhoria de desempenho, especialmente em grande número (consulte o método IntToStringFast
). No melhor caso (ou seja, a entrada mais longa possível), esse método é cerca de três vezes mais rápido. No entanto, para números de 1 dígito (ou seja, 1 dígito na base de destino), IntToString
será mais rápido.
Recentemente, escrevi sobre isso . Minha implementação não usa nenhuma operação de string durante os cálculos, o que a torna muito rápida . A conversão para qualquer sistema numérico com base de 2 a 36 é suportada:
Também implementei uma função inversa rápida caso alguém também precise: Sistema de Numeral Arbitrário para Decimal .
fonte
result = "-" + result
? Isso é algum tipo de enchimento? Como posso modificar o código para usar apenas AZ ou 0-9 para um caractere de preenchimento?"-"
inresult = "-" + result
representa o sinal negativo de números negativos. Não é um caractere de preenchimento.MÉTODOS " DE " E " PARA " RÁPIDO
Estou atrasado para a festa, mas compus respostas anteriores e as melhorei. Acho que esses dois métodos são mais rápidos do que qualquer outro postado até agora. Consegui converter 1.000.000 de números de e para a base 36 em menos de 400 ms em uma máquina de núcleo único.
O exemplo abaixo é para a base 62 . Altere a
BaseChars
matriz para converter de e para qualquer outra base.EDIT (12/07/2018)
Corrigido para resolver o caso de canto encontrado por @AdrianBotor (ver comentários) convertendo 46655 para a base 36. Isso é causado por um pequeno erro de ponto flutuante calculando
Math.Log(46656, 36)
que é exatamente 3, mas o .NET retorna3 + 4.44e-16
, o que causa um caractere extra no buffer de saída .fonte
BaseToLong(LongToBase(46655)) == 46655
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
e converter o valor46655
. O resultado deve ser,ZZZ
mas no depurador que recebo\0ZZZ
. Apenas este valor é adicional\0
. Por exemplo, o valor46654
converte corretamente paraZZY
.LongToBase
quereturn new string(buffer, (int) i, buffer.Length - (int)i);
Também é possível usar uma versão ligeiramente modificada da aceita e ajustar a sequência de caracteres de base de acordo com suas necessidades:
fonte
Muito tarde para a festa neste aqui, mas escrevi a seguinte classe auxiliar recentemente para um projeto no trabalho. Ele foi projetado para converter strings curtas em números e vice-versa (uma função hash perfeita simplista ), no entanto, também realizará a conversão de números entre bases arbitrárias. A
Base10ToString
implementação do método responde à pergunta que foi postada originalmente.O
shouldSupportRoundTripping
sinalizador passado para o construtor da classe é necessário para evitar a perda dos dígitos iniciais da string numérica durante a conversão para a base 10 e vice-versa (crucial, dados meus requisitos!). Na maioria das vezes, a perda dos 0s iniciais da sequência de números provavelmente não será um problema.Enfim, aqui está o código:
Isso também pode ser uma subclasse para derivar conversores de números personalizados:
E o código seria usado assim:
fonte
Esta classe desta postagem do fórum pode ajudá-lo?
Totalmente não testado ... deixe-me saber se funciona! (Copie e cole no caso de a postagem no fórum desaparecer ou algo assim ...)
fonte
Eu também estava procurando uma maneira rápida de converter o número decimal em outra base no intervalo de [2..36], então desenvolvi o código a seguir. É simples de seguir e usa um objeto Stringbuilder como proxy para um buffer de caracteres que podemos indexar caractere por caractere. O código parece ser muito rápido em comparação com as alternativas e muito mais rápido do que inicializar caracteres individuais em uma matriz de caracteres.
Para seu próprio uso, você pode preferir: 1 / Retornar uma string em branco em vez de lançar uma exceção. 2 / remova a verificação de raiz para fazer o método rodar ainda mais rápido 3 / Inicialize o objeto Stringbuilder com 32 '0's e remova o resultado da linha.Remove (0, i) ;. Isso fará com que a string seja retornada com zeros à esquerda e aumentará ainda mais a velocidade. 4 / Faça do objeto Stringbuilder um campo estático dentro da classe, portanto, não importa quantas vezes o método DecimalToBase seja chamado, o objeto Stringbuilder só é inicializado uma vez. Se você fizer essa alteração, 3 acima não funcionará mais.
Espero que alguém ache isso útil :)
AtomicParadox
fonte
Eu estava usando isso para armazenar um Guid como uma string mais curta (mas estava limitado a usar 106 caracteres). Se alguém estiver interessado, aqui está o meu código para decodificar a string de volta para um valor numérico (neste caso, usei 2 ulongs para o valor Guid, em vez de codificar um Int128 (já que estou no 3.5 e não no 4.0). Para maior clareza, CODE é um string const com 106 caracteres exclusivos. ConvertLongsToBytes é bastante monótono.
fonte
Eu tinha uma necessidade semelhante, exceto que precisava fazer matemática sobre os "números" também. Peguei algumas das sugestões aqui e criei uma classe que vai fazer toda essa diversão. Ele permite que qualquer caractere Unicode seja usado para representar um número e também funciona com decimais.
Esta classe é muito fácil de usar. Basta criar um número como um tipo de
New BaseNumber
, definir algumas propriedades e desligar. As rotinas se encarregam de alternar entre a base 10 e a base x automaticamente e o valor que você define é preservado na base que você define, então nenhuma precisão é perdida (até a conversão, mas mesmo assim a perda de precisão deve ser mínima, pois isso usos de rotinaDouble
eLong
sempre que possível).Não posso controlar a velocidade dessa rotina. Provavelmente é muito lento, então não tenho certeza se atenderá às necessidades de quem fez a pergunta, mas é flexível, então espero que outra pessoa possa usar isso.
Para qualquer outra pessoa que possa precisar desse código para calcular a próxima coluna no Excel, incluirei o código de loop que usei para aproveitar essa classe.
E agora, para o código percorrer as colunas do Excel:
Você notará que a parte importante da parte do Excel é que 0 é identificado por um @ no número refeito. Então, eu apenas filtro todos os números que têm um @ neles e obtenho a sequência adequada (A, B, C, ..., Z, AA, AB, AC, ...).
fonte
fonte
Se alguém está procurando uma opção VB, isso foi baseado na resposta de Pavel:
fonte
Esta é uma maneira bastante direta de fazer isso, mas pode não ser a mais rápida. É muito poderoso porque pode ser composto.
Combine isso com este método de extensão simples e qualquer obtenção de base agora é possível:
Ele pode ser usado assim:
O resultado é:
fonte