Convert.ToString
dapat digunakan untuk mengubah angka menjadi representasi string ekuivalennya dalam basis yang ditentukan.
Contoh:
string binary = Convert.ToString(5, 2); // convert 5 to its binary representation
Console.WriteLine(binary); // prints 101
Namun, seperti yang ditunjukkan oleh komentar, Convert.ToString
hanya mendukung set basis terbatas berikut - tetapi biasanya cukup -: 2, 8, 10, atau 16.
Perbarui (untuk memenuhi persyaratan untuk mengonversi ke basis mana pun):
Saya tidak mengetahui metode apa pun di BCL yang mampu mengonversi angka menjadi basis apa pun sehingga Anda harus menulis fungsi utilitas kecil Anda sendiri. Contoh sederhana akan terlihat seperti itu (perhatikan bahwa ini pasti dapat dibuat lebih cepat dengan mengganti rangkaian 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);
}
}
Perbarui 2 (Peningkatan Kinerja)
Menggunakan buffer array sebagai ganti penggabungan string untuk membangun string hasil memberikan peningkatan kinerja terutama pada jumlah yang besar (lihat metode IntToStringFast
). Dalam kasus terbaik (yaitu masukan terpanjang mungkin) metode ini kira-kira tiga kali lebih cepat. Namun, untuk angka 1 digit (yaitu 1 digit di basis target), IntToString
akan lebih cepat.
Saya baru-baru ini membuat blog tentang ini . Implementasi saya tidak menggunakan operasi string apa pun selama kalkulasi, yang membuatnya sangat cepat . Konversi ke sistem angka apa pun dengan basis dari 2 hingga 36 didukung:
Saya juga telah mengimplementasikan fungsi invers cepat jika ada yang membutuhkannya juga: Sewaktu-waktu ke Sistem Angka Desimal .
sumber
result = "-" + result
? Apakah itu semacam bantalan? Bagaimana saya bisa mengubah kode sehingga saya hanya menggunakan AZ atau 0-9 untuk karakter padding?"-"
diresult = "-" + result
tribun untuk tanda negatif dari angka negatif. Ini bukan karakter padding.METODE " DARI " DAN " KE " CEPAT
Saya terlambat ke pesta, tetapi saya menggabungkan jawaban sebelumnya dan memperbaikinya. Saya pikir kedua metode ini lebih cepat daripada yang lain yang diposting sejauh ini. Saya dapat mengubah 1.000.000 angka dari dan ke basis 36 di bawah 400ms dalam satu mesin inti.
Contoh di bawah ini untuk basis 62 . Ubah
BaseChars
larik yang akan diubah dari dan ke basis lainnya.EDIT (2018-07-12)
Memperbaiki untuk mengatasi kasus sudut yang ditemukan oleh @AdrianBotor (lihat komentar) yang mengubah 46655 menjadi basis 36. Ini disebabkan oleh kesalahan titik mengambang kecil
Math.Log(46656, 36)
yang menghitung persis 3, tetapi .NET kembali3 + 4.44e-16
, yang menyebabkan karakter tambahan dalam buffer keluaran .sumber
BaseToLong(LongToBase(46655)) == 46655
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
dan mengonversi nilai46655
. Hasilnya harusZZZ
tetapi di debugger yang saya dapatkan\0ZZZ
. Hanya nilai ini yang mendapat tambahan\0
. Misalnya nilai46654
diubah dengan benar menjadiZZY
.LongToBase
kereturn new string(buffer, (int) i, buffer.Length - (int)i);
Seseorang juga dapat menggunakan versi yang sedikit dimodifikasi dari yang diterima dan menyesuaikan string karakter dasar dengan kebutuhannya:
sumber
Sangat terlambat ke pesta yang satu ini, tetapi saya menulis kelas pembantu berikut baru-baru ini untuk sebuah proyek di tempat kerja. Ini dirancang untuk mengubah string pendek menjadi angka dan kembali lagi ( fungsi hash sempurna yang sederhana ), namun juga akan melakukan konversi angka antara basis arbitrer. The
Base10ToString
metode pelaksanaan menjawab pertanyaan yang awalnya diumumkan.The
shouldSupportRoundTripping
bendera dilewatkan ke konstruktor kelas diperlukan untuk mencegah hilangnya terkemuka digit dari jumlah string yang selama konversi ke basis-10 dan kembali lagi (penting, mengingat kebutuhan saya!). Sebagian besar waktu hilangnya 0 di depan dari string angka mungkin tidak akan menjadi masalah.Bagaimanapun, ini kodenya:
Ini juga dapat disubkelas untuk mendapatkan konverter nomor kustom:
Dan kodenya akan digunakan seperti ini:
sumber
Bisakah kelas dari postingan forum ini membantu Anda?
Benar-benar belum teruji ... beri tahu saya jika berhasil! (Salin-tempel jika posting forum hilang atau sesuatu ...)
sumber
Saya juga sedang mencari cara cepat untuk mengubah angka desimal ke basis lain dalam kisaran [2..36] jadi saya mengembangkan kode berikut. Ini mudah diikuti dan menggunakan objek Stringbuilder sebagai proxy untuk buffer karakter yang dapat kita indeks karakter demi karakter. Kode tersebut tampaknya sangat cepat dibandingkan dengan alternatif dan jauh lebih cepat daripada menginisialisasi karakter individu dalam larik karakter.
Untuk penggunaan Anda sendiri, Anda mungkin memilih untuk: 1 / Mengembalikan string kosong daripada membuat pengecualian. 2 / hapus pemeriksaan radix untuk membuat metode berjalan lebih cepat 3 / Inisialisasi objek Stringbuilder dengan 32 '0 dan hapus hasil baris. Hapus (0, i) ;. Ini akan menyebabkan string dikembalikan dengan angka nol di depan dan selanjutnya meningkatkan kecepatan. 4 / Jadikan objek Stringbuilder sebagai bidang statis di dalam kelas sehingga tidak peduli berapa kali metode DecimalToBase dipanggil, objek Stringbuilder hanya dijalankan sekali. Jika Anda melakukan ini, perubahan 3 di atas tidak akan berfungsi lagi.
Saya harap seseorang menemukan ini berguna :)
AtomicParadox
sumber
Saya menggunakan ini untuk menyimpan Guid sebagai string yang lebih pendek (tetapi dibatasi untuk menggunakan 106 karakter). Jika ada yang tertarik di sini adalah kode saya untuk mendekode string kembali ke nilai numerik (dalam hal ini saya menggunakan 2 ulong untuk nilai Guid, daripada mengkodekan Int128 (karena saya di 3.5 bukan 4.0). Untuk kejelasan KODE adalah a string const dengan 106 karakter unik. ConvertLongsToBytes sangat tidak menyenangkan.
sumber
Saya memiliki kebutuhan yang sama, kecuali saya perlu mengerjakan matematika pada "angka" juga. Saya mengambil beberapa saran di sini dan membuat kelas yang akan melakukan semua hal menyenangkan ini. Ini memungkinkan karakter unicode apa pun untuk digunakan untuk mewakili angka dan berfungsi dengan desimal juga.
Kelas ini cukup mudah digunakan. Buat saja nomor sebagai jenis
New BaseNumber
, setel beberapa properti, dan nonaktifkan Anda. Rutinitas menangani peralihan antara basis 10 dan basis x secara otomatis dan nilai yang Anda tetapkan dipertahankan di basis yang Anda tetapkan, jadi tidak ada akurasi yang hilang (hingga konversi itu terjadi, tetapi bahkan kehilangan presisi harus sangat minimal karena ini penggunaan rutinDouble
danLong
jika memungkinkan).Saya tidak bisa memerintahkan kecepatan rutinitas ini. Mungkin agak lambat, jadi saya tidak yakin apakah itu akan sesuai dengan kebutuhan orang yang bertanya, tapi pasti fleksibel, jadi mudah-mudahan orang lain bisa menggunakan ini.
Bagi siapa pun yang mungkin memerlukan kode ini untuk menghitung kolom berikutnya di Excel, saya akan menyertakan kode perulangan yang saya gunakan yang memanfaatkan kelas ini.
Dan sekarang untuk kode untuk mengulang melalui kolom Excel:
Anda akan melihat bagian penting dari bagian Excel adalah bahwa 0 diidentifikasi oleh @ di nomor berbasis ulang. Jadi saya hanya menyaring semua angka yang memiliki @ di dalamnya dan saya mendapatkan urutan yang tepat (A, B, C, ..., Z, AA, AB, AC, ...).
sumber
sumber
Jika ada yang mencari opsi VB, ini didasarkan pada jawaban Pavel:
sumber
Ini adalah cara yang cukup mudah untuk melakukan ini, tetapi ini mungkin bukan yang tercepat. Ini cukup kuat karena dapat disusun.
Gabungkan ini dengan metode ekstensi sederhana ini dan mendapatkan basis apa pun sekarang dimungkinkan:
Ini bisa digunakan seperti ini:
Outputnya adalah:
sumber