开发者

Can anyone figure out what this method (in C) is doing? Trying to understand this for an assignment

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 (coun开发者_Go百科t % 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);
}


The horror with switch is Duff's device (a creatively unrolled loop, but otherwise it just copies source to destination).

tworegisterswap swaps the values pointed to by x and y using bitwise XOR.

bigintegeraverage is a sneaky way to get the average of two integers in a potentially non-portable manner but without the possibility of overflow. (See Aggregate Magic Algorithms for details.)


It's called Duff's device. It uses switch statement to implement state machines in C. In this particular case it performs one branch per 8 iterations of memcopy.

Read this for additional info: http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html

The second function swaps two integers.

The third just computes the average of two numbers, because sum can be written as

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

and by using ((a ^ b) >> 1) + (a & b) instead of (a + b >> 1) we can avoid possible overflows.


See Tom Duff on Duff's Device:

The point of the device is to express general loop unrolling directly in C. People who have posted saying `just use memcpy' have missed the point, as have those who have criticized it using various machine-dependent memcpy implementations as support. In fact, the example in the message is not implementable as memcpy, nor is any computer likely to have an memcpy-like idiom that implements it. more


That is actually 3 functions.

memorycopy()... well, someone else can figure that one out :P

tworegistervarswap() seems to take pointers to two ints, and if they don't already match, then it does some bit fiddling with them (XOR). It swaps the values without using a temporary variable.

bigintegeraverage() takes two ints and returns the mean (thanks Steve Jessop) based on them, using bit fiddling as well (AND, XOR and RIGHT SHIFT).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜