Может кто-нибудь выяснить, что делает этот метод (в C)? Пытаясь понять это для назначения - PullRequest
3 голосов
/ 18 ноября 2010
void* memorycopy (void *des, const void *src, size_t count)
{

  size_t n = (count + 7) / 8;
  char* destination = (char *) des;
  char* source = (char *) src;

  switch (count % 8)
  {
      case 0:  do{  *destination++ = *source++;
      case 7:  *destination++ = *source++;
      case 6:  *destination++ = *source++;
      case 5:  *destination++ = *source++;
      case 4:  *destination++ = *source++;
      case 3:  *destination++ = *source++;
      case 2:  *destination++ = *source++;
      case 1:  *destination++ = *source++;

    } while (--n > 0);
  }

  return des;
}




void tworegistervarswap (int *x, int *y)
{
  if (x != y)
  {
    *x = *x ^ *y;
    *y = *x ^ *y;
    *x = *x ^ *y;
  }
}



int bigintegeraverage (int x, int y)
{
  return (x & y) + ((x ^ y) >> 1);
}

Ответы [ 4 ]

3 голосов
/ 18 ноября 2010

Ужас с switch - это устройство Даффа (творчески развернутый цикл, но в противном случае он просто копирует источник в место назначения).

tworegisterswap меняет значения, на которые указывают x и y, используя битовое XOR.

bigintegeraverage - это хитрый способ получить среднее из двух целых чисел потенциально непереносимым образом, но без возможности переполнения. (Подробнее см. Алгоритмы агрегирования магии .)

1 голос
/ 18 ноября 2010

См. Том Дафф на устройстве Даффа :

Смысл устройства заключается в том, чтобы выражать общий цикл развертывания непосредственно в C. Люди, которые опубликовали сообщение "просто используйте memcpy"упустили этот момент, как и те, кто критиковал его, используя различные машинно-зависимые реализации memcpy в качестве поддержки.На самом деле, пример в сообщении не может быть реализован как memcpy, и ни один компьютер, скорее всего, не будет иметь подобную memcpy идиому, которая его реализует. больше

1 голос
/ 18 ноября 2010

Это называется устройство Даффа. Он использует оператор switch для реализации конечных автоматов в C. В этом конкретном случае он выполняет одну ветвь на 8 итераций memcopy.

Прочитайте это для дополнительной информации: http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html

Вторая функция заменяет два целых числа.

Третий просто вычисляет среднее из двух чисел, потому что сумма может быть записана как

a + b = (a ^ b) + ((a & b) << 1); // the AND here represents carry

и используя ((a ^ b) >> 1) + (a & b) вместо (a + b >> 1), мы можем избежать возможных переполнений.

0 голосов
/ 18 ноября 2010

Это фактически 3 функции.

memorycopy() ... ну, кто-то еще может понять это: P

tworegistervarswap(), кажется, берет указатели на два int с, и если они еще не совпадают, то с ними немного возится ( XOR ). Меняет значения без использования временной переменной.

bigintegeraverage() берет два int с и возвращает среднее (спасибо Стив Джессоп ) на основе их, также используя битовое перемешивание (AND, XOR и RIGHT SHIFT).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...