2010-10-04 76 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; 
}