最近学习C,感觉C确实比较接近底层,要多了解计算机基础,这一门语言就一定不能错过了,因为许多知识都从这里延伸出来。
言归正题,先说说机器数:
二进制数有正负之分,如N1=+0.101101,N2=-0.101101,则N1是个正数,N2是个负数。机器不能直接把符号“+”、“-”表示出来,为了能在计算机中表示正负数,必须引入符号位,即把正负符号也用1位二进制数码来表示。把符号位和数值位一起编码来表示相应的数的表示方法包括:原码、补码、反码、移码等。
机器数 用二进制数“0”或“1”来表示数的符号,“0”表示正号,“1”表示负号,且把符号位置于该数的最高数值位之前,这样表示的数称为机器数(或称机器码),即把符号位和数值位一起编码来表示的数就是机器数。
原码/补码/反码之间的关系:
机器数:原码与补码
对于正数而言,二进制数的原码/反码/补码都是一样的
对于负数而言,其二进制数与原码一样,其反码则是其二进制数逐位反转(0转为1,1转为0)而成,其补码则是反码的基础上加1
其中对于原码/反码和补码而言,其最高位中0代表正数,1代表负数
使用补码可使减法变加法(符号位参与运算)
负数的原码和补码之间的转换
负数的原码=负数的补码-1 再取反
负数的原码=负数的补码取反再加1
更多的知识可以参考这篇文章:
http://share.onlinesjtu.com/mod/tab/view.PHP?id=173
位移运算
说到位移运算,就必须有与、或、非、异或这几个运算符,它们二进制运算中的运算符,以下时他们的规则:
& 与运算,有0为0,全1为1;
| 或运算,有1为1,全0为0;
! 非运算,非0则1,非1则0;
^ 异或运算,相同为0,不同为1;
~ 二进制反码或按位取反运算符,把1变为0, 0变为1
& 与运算
就像规则一样,只有全部时1的时候得到的结果才为1。
示例:
(10010011)&(00111101)=(00010001)
| 或运算
当运算结果其中一个为1时,结果就为1,当然,都是1的时候也是1
示例:
(10010011)&(00111101)=(10111111)
^ 异或运算
当且仅当有一个1的时候才为1,也就是说只有1和0组合才为1
示例:
(10010011)&(00111101)=(10101110)
~ 取反运算符
将二进制逐位取反
示例:
~(10011010) = (01100101)
用法
了解这四个运算符很简单,但是对于初学者而言,更重要的是其用法,如果不知道怎么用,那么这道这些运算符也没什么用
& 运算符用法:掩码
与运算符通常用于掩码,指的是一些设置为开(1)或管(0)的为组合。
在实际运用中,最常见的掩码用法莫过于以下这种:
ch & 0xff
其中0xff的二进制形式为11111111,当一个数与上0xff,那么此数的最后8位将保存不变(&运算规则决定),而其他数均会为0,也就是说最终的值被改为1个8为字节,这种用法是取位的某一段。
第二种用法是让某些位或某一位为0,因为&运算的规则,只要给某些位上&上为0的数,那么这一位就会为0,如上面的示例(10010011)&(00111101)=(00010001)
| 运算符用法
使一个位或几个位为1,如x|0x01,这样不管x是什么数,其结果的最后一位都会为1。
把两个数拼起来,如0xFF00 | 0x00FF
~ 取反用法
想得到全部位为1的数,如~0
移位运算
移位运算分<<左移和>> 右移。
其中<<左移的结果将会乘以2的n次幂,其中左移末端位的值丢失时,用0补足
>>右移的结果将会除以2的n次幂,移出右末端位的值丢弃。unsigned类型,左侧填0;signed类型,左侧保持不变(保持符号),如10000000>>1 = 11000000