二进制的 0 和 1
人类我们常用的数据表示方法是十进制,而计算机却是二进制,在计算机的设备里面所有的数据都是使用二进制表示的。显示器显示的数据是人类能理解的数据,这是为了更好的和人类交互这样的设计的,当在键盘上输入一个内容的时候,这些在计算机内部处理完全是二进制的,计算机只认识 0
和 1
,也是二进制位。
计算机最基础的计量单位是 bit
,也就是 8
个比特位等于一个 byte
字节,后面的计量单位在当前计量基础做 10^2 计算,相关的存储单位可以去看看相关资料,这篇 blog
我就不会详细的介绍这些计量单位。
用比特位存储表示详细的话,如果把8个比特位填满那么可以表示为 255 ,如果 8 比特位都是0的话那么就是 0 。
如果某些时候在追求计算性能和存储空间利用率的时候,可以使用位运算,如果需要表示的信息状态只要两种的话可以使用位图来表示,这样空间利用率会更好,本文就介绍一下关于位运算的基础和位图。
说一句话就是:与二一是 1 ,或二零是 0 ,异或相同为 0 ,相异为 1 ,取反就是反。
计算两个数的和,因为在计算机中都是以二进制来进行运算,所以下面所给的 int
变量会在机器内部先转换为二进制在进行相加,例如下图动图:
在我们人类世界里是逢十进一
,在计算机的二进制里面逢二进一
,计算过程:
183: 1 0 1 1 0 1 1 1
+ 19: 0 0 1 0 0 0 1 1
——————————————————————————
202: 1 1 0 0 1 0 1 0
在计算机运算里面,加减乘除都是通过加法实现的,这部分内容比较深奥,涉及一些知识,读者可以下面这个视频:
位图实现
位图就是利用的比特位作为基础的一种数据结构的应用,可以使用少量的内存占用表示更多数据信息,例如我在 Go
语言里面使用了 int16
作为基础存储空间,这样 int16
是由 2 个 byte
组成的,可以表示 512
状态信息。位图就是使用这一特性来解决的问题状态信息表示的问题,例如下面实现代码:
package bitmap
type Bits struct {
bytes []int16
nbits int
}
//把需要表示数量除以16得到需要分配的int16个数
func New(nbits int) Bits {
return Bits{
nbits: nbits,
bytes: make([]int16, nbits/16+1),
}
}
// 通过下标对16取商得到具体那块内存
// 然后对其内存的bit位进行设置
func (m *Bits) Set(index int) {
if index > m.nbits {
return
}
byteIndex := index / 16
bitIndex := index % 16
m.bytes[byteIndex] |= (1 << bitIndex)
}
func (m *Bits) Peek(index int) bool {
if index > m.nbits {
return false
}
byteIndex := index / 16
bitIndex := index % 16
return (m.bytes[byteIndex] & (1 << bitIndex)) != 0
}