Преобразовать строку из 4 символов в int32 - PullRequest
4 голосов
/ 05 октября 2010

Есть ли быстрый способ конвертировать 4 символа в 32-битное int?Я знаю, что могу пройти через это как:

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 символов в целочисленный указатель местоположения.

Ответы [ 4 ]

8 голосов
/ 05 октября 2010

Вы можете сначала преобразовать строку в байтовый массив, используя соответствующую кодировку (см. 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 дает результат, который зависит от порядкового номера машины, на которой он работает. Если вы хотите, чтобы код был независимым от платформы, вы можете посмотреть на EndianBitConverter в библиотеке Jon Skeet MiscUtil .


Производительность

Я тестировал производительность трех реализаций:

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, вероятно, подходит для большинства ситуаций, когда производительность не критична (если вы не возражаете, что она работает только на компьютерах с прямым порядком байтов).

3 голосов
/ 05 октября 2010

Использовать байты и битконвертер:

byte[] bytes = ...;
int i = BitConverter.ToInt32(bytes, 0)
2 голосов
/ 05 октября 2010

Обратите внимание, что строки в C # содержат символы Unicode, а не байты. Я не знаю, какую проблему вы хотите решить с помощью этого вопроса, но учтите, что вы можете конвертировать только 4 байт в 32-разрядное целое число. Преобразование строки Unicode имеет смысл, только если вы делаете предположения о байтовой кодировке. Поэтому, если вы хотите трактовать текст как Windows-1252 (очень распространенная кодировка Windows), вы должны сначала закодировать строку и преобразовать байты в целочисленное значение.

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

Результат - res == 0xD6434241 (на машине с прямым порядком байтов). 0xD6 - это номер Windows-1252 для «Ö».

В зависимости от вашей проблемы, вы, скорее всего, захотите использовать байты напрямую (Стефан Штайнеггер предложил это уже).

0 голосов
/ 08 апреля 2015

Проще, лучше:

/*
** 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...