进制、位运算笔记

进制介绍

  一种计数的方式,数值的表示形式。

  常见的进制有:二进制、十进制、八进制和十六进制。

二进制:

  0和1,C语言中表示0b开头或者0B开头。

八进制:

  0,1,2,3,4,5,6,7 C语言中以0开头的数字,例如045

十进制:

  自然数

十六进制:

  0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F C语言中以0x或者0X开头的数字

进制之间的转换:

  其他进制转换成十进制的三要素:

  1. 数位:数码在一个数中所处的位置。 一个序列,从右往左数位依次是0,1,2,3 ...

  2. 基数: 几进制基数就是几

  3. 位权: 位权 = 数码值 * 基数 ^ 数位

  各位权之和就就是这个数转换成10进制后的表示形式。

十进制转二进制:

  除2取余,把余数的序列倒过来就是该数的二进制表示。

二进制转十进制:

  所有位权相加

二进制转十六进制:

  整数部分,四位二进制从左向右结合;小数部分从右向左结合;

十六进制:

  一拆四;

二进制转八进制:

  三合一;

八进制转二进制:

  一拆三;

机器数:

  一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机 用一个数的最高位存放符号, 正数为0, 负数为1.

真值:

  将带符号位的机器数对应的真正数值称为机器数的真值。 

  因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于 131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。

 

原码、反码、补码:

   数据在计算机中的存储方法数据在计算机内部是以补码的形式储存的

   数据分为有符号数和无符号数:

   无符号数都为正数,由十进制直接转换到二进制直接存储(其实也是该十进制的补码)即可。有符号数用在计算机内部是以补码的形式储存的。( 正数的最高位是符号位0,负数的最高位是 符号位1

 对于正数:反码==补码==原码。 对于负数:反码==除符号位以外的各位取反。补码= +1)

 

以二进制的补码存储

   正数:原码、反码、补码都相同 

   负数:反码 = 源码取反,补码 = 反码+1 或者 补码 = 源码取反 + 1前提都是符号位不变

   正数的首位地址为0,其原码是由十进制数转换到的二进制数字

  负数的首位地址为1,其原码后面的位也为10进制数转换过去的二进制数字,都是用补码方式表示 有符号数的。

 1)原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值.

2)反码

反码的表示方法是:正数的反码是其本身;负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

3)补码

补码的表示方法是:正数的补码就是其本身;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

 

位运算

  位运算是指按二进制进行的运算。在系统软件中,常常需要处理二进制位的问题。C语言提供了6个位操作运算符。这些运算符只能用于整型操作数,即只能用于带符号或无符号的 char,short,intlong类型。

1)& 按位与   口诀: 11,00

只有对应的两个二进位均为1,结果位才为1,否则为0 

2) | 按位或    口诀:11

只要对应的二个二进位有一个为1,结果位就为1,否则为0

 3) ^ 按位异或  口诀:01

当对应的二进位相异(不相同),结果为1,否则为0

4)~ 取反

各二进位进行取反(01,10)

   以上都是在二进制进行运算

1)<<  左移

   1、各二进位全部左移n,高位丢弃,低位补0

     1)左移可能会改变一个数的正负性

     2)左移1位相当于*2^n

 举例:快速计算一个数乘以2n次方

(8<<3 等同于8*2^3)

 

2)>> 右移

  各二进位全部右移n,保持符号位不变

x >> n,x的所有二进制位向右移动n,移出的位删掉,移进的位补符号位

 1、右移不会改变一个数的符号

2  右移 n 位就相当于/2^n

用途:快速计算一个数除以2n次方 (8>>3 等同于8/2^3)

 

技巧:

1)任何数和1进行&操作,得到这个数的最低位

2)想把某一位置0,就让它某一位置与0进行&运算

 

练习题:

 1 /*
 2  编写一个移位函数,使移位函数既能循环左移又能循环右移。参数n大于0时便是左移,参数n小于0时便是右移
 3  
 4  解释:循环右移:把右边移出的位放到左边移入的位
 5  如: 1101 0101 1100 循环左移四位  0101 1100 1101
 6  
 7  循环左移:把左边移出的位放到右边移入的位
 8  */
 9 #include <stdio.h>
10 
11 unsigned bitTransfer(unsigned, int);//函数声明
12 
13 int main(int argc, const char * argv[]){
14     unsigned a = 9;
15     int n = 10;
16     
17     unsigned b = bitTransfer(a, n);
18     
19     printf("无符号数9位移10位后的数是:%u
", b);
20     
21 }
22 /**
23  *  @author 司英成, 15-06-25 21:06:59
24  *
25  *  @param number 要移位的数
26  *  @param n      移位的位数
27  *
28  *  @return 移位后的数
29  */
30 unsigned bitTransfer(unsigned number, int n){
31     if (n > 0)
32         return (number << n) ^ (number >> (32 - n));
33     else{
34         n = - n;
35         return (number >> n) ^ (number << (32 - n));
36     }
37 }
原文地址:https://www.cnblogs.com/siyingcheng/p/4601015.html