Friday, January 15, 2010

数另一种计算方法

朋友说, 这种技术可以从这书中得到: www.hackersdelight.org

只是没有必要去看. 了解这种用法, 只是为了看懂glibc罢了. 没有它意.

得到负数的方法


C语言里的“位与”, “位或“, ”取反“, 在数的计算中, 相当活用。

void main(int argc, char *argv[])
{
  printf("%x\n", 2);
  printf("%x\n", -2);
  printf("%x\n", ~2);
  printf("%x\n", ~2 + 1);
}
输出結果:
2
fffffffe
fffffffd
fffffffe

可以得到 -2 == (~2 + 1)

实际上就是补码: http://baike.baidu.com/view/377340.htm

divmod的算术

在glibc/string/strncmp.c中, 可以看到divmod的方法:

size_t n4 = n >> 2; n4就是商

n &= 3; 就是除以4后的余数. 因为最后两位情况是0到3, 不可能被4除.

">>"和"<<"只合适乘以2^n和除以2^n

用"&"求余又要方便, 只合适求除以2^n后的余数.

余数的求法

和前面的divmod有关系, 都是余数的问题, 只是不够深刻, 来一个深刻一些的例子:

代码来自于glibc/string/strnlen.c

 /* Handle the first few characters by reading one character at a time.
     Do this until CHAR_PTR is aligned on a longword boundary.  */
  for (char_ptr = str; ((unsigned long int) char_ptr
      & (sizeof (longword) - 1)) != 0
;
       ++char_ptr)
    if (*char_ptr == '\0')
      {
  if (char_ptr > end_ptr)
    char_ptr = end_ptr;
  return char_ptr - str;
      }
longword其实就是long int , 等于本人的电脑等于4
上面蓝色的代码就是求除以 longword 后, 余数是否为0



No comments:

Post a Comment

Note: Only a member of this blog may post a comment.