2010-10-04 110 views
3

是否有一種將4個字符轉換爲32位int的快速方法?我知道我可以遍歷它想:將4個字符串轉換爲int32

string key = "ABCD"; 
int val = 0; 
for (int i = 0; i < 4; i++) 
{ 
    int b = (int)key[i] * (int)Math.Pow(256, i); 
    val += b; 
} 
// val = 1145258561 

我想的東西較低的水平,我所知道的字符存儲爲字節。我不介意它的不安全的代碼,因爲我基本上試圖寫一個4個字符串到一個整數指針位置。

+3

不要忘了,在C#字符都是Unicode,並採取16位而不是8 – 2010-10-04 20:36:54

回答

7

你可以先轉換成字符串使用適當的編碼字節數組(見Encoding.GetEncoding),那麼你可以使用BitConverter.ToInt32字節數組轉換爲整數。

string s = "ABCD"; 
byte[] bytes = encoding.GetBytes(s); /* Use the correct encoding here. */ 
int result = BitConverter.ToInt32(bytes, 0); 

結果:

1145258561 

要返回從整數字符串中,你簡單地恢復過程:

int i = 1145258561; 
byte[] bytes = BitConverter.GetBytes(i); 
string s = encoding.GetString(bytes); 

結果:

ABCD 

注意BitConverter類給出了一個依賴的結果不知道它運行的機器的字節順序。如果你想讓代碼獨立於平臺,你可以在Jon SkeetMiscUtil庫中查看EndianBitConverter。


性能

我測試了三種實現的性能:

Math.Pow

int convert1(string key) 
{ 
    int val = 0; 
    for (int i = 0; i < 4; i++) 
    { 
     int b = (int)key[i] * (int)Math.Pow(256, i); 
     val += b; 
    } 
    return val; 
} 

BitConverter

int convert2(string key) 
{ 
    byte[] bytes = encoding.GetBytes(key); 
    int result = BitConverter.ToInt32(bytes, 0); 
    return result; 
} 

比特移位

int convert3(string key) 
{ 
    int val = 0; 
    for (int i = 3; i >= 0; i--) 
    { 
     val <<= 8; 
     val += (int)key[i]; 
    } 
    return val; 
} 

環展開

int convert4(string key) 
{ 
    return (key[3] << 24) + (key[2] << 16) + (key[1] << 8) + key[0]; 
} 

結果

最大是最佳的性能:

 
Method   Iterations per second 
------------------------------------ 
Math.Pow      690000 
BitConverter     2020000 
Bit shifting     4940000 
Loop unrolled    8040000 

結論

如果性能是至關重要的,那麼寫自己的方法做位移獲得最佳性能。對於性能不重要的大多數情況(假設您不介意它僅適用於小型端計算機),使用標準類BitConverter可能沒有問題。

+0

的作品真的很好,謝謝!我會看看它對我來說足夠快。有沒有辦法將其翻轉回來? – Proviance 2010-10-04 21:04:03

+1

重要的是,這隻會對ASCII字符正確工作。 'ASCIIEncoding'(或一般的'Encoding'類)實現得非常愚蠢:它只是用'?'替換字符。如果它們不能被編碼。 – AndiDog 2010-10-04 21:07:26

+0

謝謝!位移是我正在尋找的。我從來沒有做過任何位移C#,但我知道它必須在那裏 – Proviance 2010-10-04 21:52:46

3

使用字節,BitConverter:

byte[] bytes = ...; 
int i = BitConverter.ToInt32(bytes, 0) 
2

請注意,C#中的字符串包含Unicode字符,而不是字節。我不知道這個問題想要解決什麼樣的問題,但是請注意,您只能將4 字節轉換爲32位整數。如果您對字節編碼進行了假設,轉換Unicode字符串纔有意義。因此,如果您想將文本視爲Windows-1252(非常常見的Windows charset),則應首先對字符串進行編碼,然後將字節轉換爲整數值。

byte[] bytes = Encoding.GetEncoding(1252).GetBytes("ABCÖ"); 
uint res = BitConverter.ToUInt32(bytes, 0); 

結果是res == 0xD6434241(在一個little endian機器上)。 0xD6是'Ö'的Windows-1252號碼。

根據您的問題,您可能更希望直接使用字節(Stefan Steinegger已建議)。

+0

謝謝。我正在內存塊中創建一個aTree鏈接列表。 4個字符實際上是字典的關鍵字,所以我只是對它們進行哈希處理。我不需要擔心unicode(whew)。 – Proviance 2010-10-04 21:30:49

-1

更簡單,它能夠更好:

/* 
** Made by CHEVALLIER Bastien 
** Prep'ETNA Promo 2019 
*/ 

#include <stdio.h> 

int main() 
{ 
    int i; 
    int x; 
    char e = 'E'; 
    char t = 'T'; 
    char n = 'N'; 
    char a = 'A'; 

    ((char *)&x)[0] = e; 
    ((char *)&x)[1] = t; 
    ((char *)&x)[2] = n; 
    ((char *)&x)[3] = a; 

    for (i = 0; i < 4; i++) 
    printf("%c\n", ((char *)&x)[i]); 
    return 0; 
}