Convert.ToString
kann verwendet werden, um eine Zahl in ihre entsprechende Zeichenfolgendarstellung in einer angegebenen Basis zu konvertieren.
Beispiel:
string binary = Convert.ToString(5, 2); // convert 5 to its binary representation
Console.WriteLine(binary); // prints 101
Wie in den Kommentaren hervorgehoben, werden jedoch Convert.ToString
nur die folgenden begrenzten - aber normalerweise ausreichenden - Basissätze unterstützt: 2, 8, 10 oder 16.
Update (um die Anforderung zu erfüllen, auf eine beliebige Basis zu konvertieren):
Mir ist keine Methode in der BCL bekannt, mit der Zahlen in eine beliebige Basis konvertiert werden können, sodass Sie Ihre eigene kleine Dienstprogrammfunktion schreiben müssten. Ein einfaches Beispiel würde so aussehen (beachten Sie, dass dies sicherlich durch Ersetzen der Zeichenfolgenverkettung beschleunigt werden kann):
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);
}
}
Update 2 (Leistungsverbesserung)
Die Verwendung eines Array-Puffers anstelle der Verkettung von Zeichenfolgen zum Erstellen der Ergebniszeichenfolge führt zu einer Leistungsverbesserung, insbesondere bei großen Zahlen (siehe Methode IntToStringFast
). Im besten Fall (dh bei der längsten möglichen Eingabe) ist diese Methode ungefähr dreimal schneller. Bei 1-stelligen Zahlen (dh 1-stellig in der Zielbasis) ist IntToString
dies jedoch schneller.
Ich habe kürzlich darüber gebloggt . Meine Implementierung verwendet während der Berechnungen keine Zeichenfolgenoperationen, was sie sehr schnell macht . Die Konvertierung in ein beliebiges Zahlensystem mit einer Basis von 2 bis 36 wird unterstützt:
Ich habe auch eine schnelle Umkehrfunktion implementiert, falls jemand sie auch benötigt: Arbitrary to Decimal Numeral System .
quelle
result = "-" + result
? Ist das eine Art Polsterung? Wie kann ich den Code so ändern, dass ich nur AZ oder 0-9 für ein Füllzeichen verwende?"-"
Inresult = "-" + result
steht für das negative Vorzeichen negativer Zahlen. Es ist kein Polstercharakter.SCHNELLE " VON " UND " ZU " METHODEN
Ich bin zu spät zur Party, aber ich habe frühere Antworten zusammengesetzt und sie verbessert. Ich denke, diese beiden Methoden sind schneller als alle anderen bisher veröffentlichten. Ich konnte 1.000.000 Zahlen von und zu Basis 36 in weniger als 400 ms in einer Single-Core-Maschine konvertieren.
Das folgende Beispiel gilt für die Basis 62 . Ändern Sie das
BaseChars
Array, um es von und zu einer anderen Basis zu konvertieren.EDIT (2018-07-12)
Behoben, um den von @AdrianBotor (siehe Kommentare) gefundenen Eckfall zu beheben, der 46655 in Basis 36 konvertiert. Dies wird durch einen kleinen Gleitkommafehler verursacht,
Math.Log(46656, 36)
der genau 3 berechnet , aber .NET zurückgibt3 + 4.44e-16
, was ein zusätzliches Zeichen im Ausgabepuffer verursacht .quelle
BaseToLong(LongToBase(46655)) == 46655
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
und konvertieren den Wert46655
. Ergebnis sollte sein,ZZZ
aber im Debugger bekomme ich\0ZZZ
. Nur dieser Wert wird zusätzlich\0
. Zum Beispiel wird der Wert46654
ordnungsgemäß in konvertiertZZY
.LongToBase
anreturn new string(buffer, (int) i, buffer.Length - (int)i);
Sie können auch eine leicht modifizierte Version der akzeptierten Version verwenden und die Zeichenfolge der Basiszeichen an ihre Bedürfnisse anpassen:
quelle
Sehr spät zur Party, aber ich habe kürzlich die folgende Helferklasse für ein Projekt bei der Arbeit geschrieben. Es wurde entwickelt, um kurze Zeichenfolgen in Zahlen und wieder zurück umzuwandeln (eine vereinfachte, perfekte Hash- Funktion), es wird jedoch auch eine Zahlenumwandlung zwischen beliebigen Basen durchgeführt. Die
Base10ToString
Methodenimplementierung beantwortet die ursprünglich gestellte Frage.Das
shouldSupportRoundTripping
an den Klassenkonstruktor übergebene Flag wird benötigt, um den Verlust führender Ziffern aus der Zahlenfolge während der Konvertierung in Basis-10 und wieder zurück zu verhindern (entscheidend angesichts meiner Anforderungen!). Meistens ist der Verlust führender Nullen aus der Zahlenfolge wahrscheinlich kein Problem.Wie auch immer, hier ist der Code:
Dies kann auch in Unterklassen unterteilt werden, um benutzerdefinierte Zahlenkonverter abzuleiten:
Und der Code würde so verwendet:
quelle
Könnte Ihnen diese Klasse aus diesem Forumsbeitrag helfen?
Völlig ungetestet ... lass es mich wissen, wenn es funktioniert! (Kopieren Sie es für den Fall, dass der Forumsbeitrag verschwindet oder so ...)
quelle
Auch ich suchte nach einer schnellen Möglichkeit, die Dezimalzahl in eine andere Basis im Bereich von [2..36] umzuwandeln, und entwickelte den folgenden Code. Es ist einfach zu befolgen und verwendet ein Stringbuilder-Objekt als Proxy für einen Zeichenpuffer, den wir zeichenweise indizieren können. Der Code scheint im Vergleich zu Alternativen sehr schnell und viel schneller zu sein als das Initialisieren einzelner Zeichen in einem Zeichenarray.
Für Ihren eigenen Gebrauch bevorzugen Sie möglicherweise Folgendes: 1 / Geben Sie eine leere Zeichenfolge zurück, anstatt eine Ausnahme auszulösen. 2 / Entfernen Sie die Radix-Prüfung, damit die Methode noch schneller ausgeführt wird. 3 / Initialisieren Sie das Stringbuilder-Objekt mit 32 '0' und entfernen Sie das Zeilenergebnis. Entfernen Sie (0, i);. Dadurch wird die Zeichenfolge mit führenden Nullen zurückgegeben und die Geschwindigkeit weiter erhöht. 4 / Machen Sie das Stringbuilder-Objekt zu einem statischen Feld innerhalb der Klasse, sodass das Stringbuilder-Objekt unabhängig davon, wie oft die DecimalToBase-Methode aufgerufen wird, nur einmal initialisiert wird. Wenn Sie diese Änderung 3 oben tun, würde nicht mehr funktionieren.
Ich hoffe jemand findet das nützlich :)
AtomicParadox
quelle
Ich habe dies verwendet, um eine Guid als kürzere Zeichenfolge zu speichern (war jedoch auf 106 Zeichen beschränkt). Wenn jemand interessiert ist, ist hier mein Code zum Dekodieren der Zeichenfolge zurück in einen numerischen Wert (in diesem Fall habe ich 2 ulongs für den Guid-Wert verwendet, anstatt einen Int128 zu codieren (da ich in 3.5 nicht 4.0 bin). Aus Gründen der Klarheit ist CODE a string const mit 106 eindeutigen Zeichen. ConvertLongsToBytes ist ziemlich aufregend.
quelle
Ich hatte ein ähnliches Bedürfnis, außer dass ich auch mit den "Zahlen" rechnen musste. Ich habe einige der Vorschläge hier aufgegriffen und eine Klasse erstellt, die all diese lustigen Dinge erledigt. Es ermöglicht die Verwendung eines beliebigen Unicode-Zeichens zur Darstellung einer Zahl und funktioniert auch mit Dezimalstellen.
Diese Klasse ist ziemlich einfach zu bedienen. Erstellen Sie einfach eine Zahl als eine Art von
New BaseNumber
, legen Sie einige Eigenschaften fest und los geht's. Die Routinen sorgen dafür, dass automatisch zwischen Basis 10 und Basis x umgeschaltet wird und der von Ihnen festgelegte Wert in der Basis erhalten bleibt, in der Sie ihn festgelegt haben, sodass keine Genauigkeit verloren geht (bis zur Konvertierung, aber selbst dann sollte der Genauigkeitsverlust seitdem sehr gering sein RoutineverwendungenDouble
undLong
wo immer möglich).Ich kann die Geschwindigkeit dieser Routine nicht bestimmen. Es ist wahrscheinlich ziemlich langsam, daher bin ich mir nicht sicher, ob es den Bedürfnissen desjenigen entspricht, der die Frage gestellt hat, aber es ist sicher flexibel, sodass hoffentlich jemand anderes dies verwenden kann.
Für alle anderen, die diesen Code zur Berechnung der nächsten Spalte in Excel benötigen, werde ich den von mir verwendeten Schleifencode einschließen, der diese Klasse nutzt.
Und jetzt, damit der Code die Excel-Spalten durchläuft:
Sie werden feststellen, dass der wichtige Teil des Excel-Teils darin besteht, dass 0 in der neu basierten Nummer durch ein @ gekennzeichnet ist. Also filtere ich einfach alle Zahlen heraus, die ein @ enthalten, und erhalte die richtige Reihenfolge (A, B, C, ..., Z, AA, AB, AC, ...).
quelle
quelle
Wenn jemand eine VB-Option sucht, basiert dies auf Pavel's Antwort:
quelle
Dies ist ein ziemlich einfacher Weg, aber möglicherweise nicht der schnellste. Es ist ziemlich mächtig, weil es zusammensetzbar ist.
Kombinieren Sie dies mit dieser einfachen Erweiterungsmethode und es ist jetzt möglich, eine Basis zu erhalten:
Es kann folgendermaßen verwendet werden:
Die Ausgabe ist:
quelle