iOS 进制和位运算的应用
进制
进制也就是进位制,是人们规定的一种进位方法。 对于任何一种进制—X进制,就表示某一位置上的数运算时是逢X进一位。 十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,以此类推,x进制就是逢x进位。
进制转换
1、二进制转十进制
方法:二进制数从低位到高位(即从右往左)计算,第0位的权值是2的0次方,第1位的权值是2的1次方,第2位的权值是2的2次方,依次递增下去,把最后的结果相加的值就是十进制的值了。
例:将二进制的(101011)B转换为十进制的步骤如下:
-
第0位 1 x 2^0 = 1;
-
第1位 1 x 2^1 = 2;
-
第2位 0 x 2^2 = 0;
-
第3位 1 x 2^3 = 8;
-
第4位 0 x 2^4 = 0;
-
第5位 1 x 2^5 = 32;
-
读数,把结果值相加,1+2+0+8+0+32=43,即(101011)B=(43)D。
2、八进制转十进制
八进制 → 十进制
方法:八进制数从低位到高位(即从右往左)计算,第0位的权值是8的0次方,第1位的权值是8的1次方,第2位的权值是8的2次方,依次递增下去,把最后的结果相加的值就是十进制的值了。
八进制就是逢8进1,八进制数采用 0~7这八数来表达一个数。
例:将八进制的(53)O转换为十进制的步骤如下:
-
第0位 3 x 8^0 = 3;
-
第1位 5 x 8^1 = 40;
-
读数,把结果值相加,3+40=43,即(53)O=(43)D。
3、十六进制转十进制
方法:十六进制数从低位到高位(即从右往左)计算,第0位的权值是16的0次方,第1位的权值是16的1次方,第2位的权值是16的2次方,依次递增下去,把最后的结果相加的值就是十进制的值了。
十六进制就是逢16进1,十六进制的16个数为0123456789ABCDEF。
例:将十六进制的(2B)H转换为十进制的步骤如下:
-
第0位 B x 16^0 = 11;
-
第1位 2 x 16^1 = 32;
-
读数,把结果值相加,11+32=43,即(2B)H=(43)D。
4、十进制转二进制
方法:除2取余法,即每次将整数部分除以2,余数为该位权上的数,而商继续除以2,余数又为上一个位权上的数,这个步骤一直持续下去,直到商为0为止,最后读数时候,从最后一个余数读起,一直到最前面的一个余数。
例:将十进制的(43)D转换为二进制的步骤如下:
-
将商43除以2,商21余数为1;
-
将商21除以2,商10余数为1;
-
将商10除以2,商5余数为0;
-
将商5除以2,商2余数为1;
-
将商2除以2,商1余数为0;
-
将商1除以2,商0余数为1;
-
读数,因为最后一位是经过多次除以2才得到的,因此它是最高位,读数字从最后的余数向前读,101011,即(43)D=(101011)B。
......
暂时关于进制就介绍到这里。
iOS 中的位运算
先来看一段代码:
UNNotificationPresentationOptionBadge|
UNNotificationPresentationOptionSound|
UNNotificationPresentationOptionAlert
这是在做做APNS推送时有用到,需要设置推送的提醒方式,这里的意思是,提醒方式为:徽标或声音或提示框。我们尝试打印一下:
NSLog(@"%lu",UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound| UNNotificationPresentationOptionAlert)
输出的结果是 7,来看看是为什么?
typedef NS_OPTIONS(NSUInteger, UNNotificationPresentationOptions) {
UNNotificationPresentationOptionBadge = (1 << 0),
UNNotificationPresentationOptionSound = (1 << 1),
UNNotificationPresentationOptionAlert = (1 << 2),
} __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
UNNotificationPresentationOptionBadge = (1 << 0) : 表示00000001左移0位 = 00000001
UNNotificationPresentationOptionSound = (1 << 1):表示00000001左移1位 = 00000010
UNNotificationPresentationOptionAlert = (1 << 2) :表示00000001左移2位 = 00000100
左移运算符 <<
公式 x << 3 就是把x的各二进位左移3位
1<<1 实际就是 0001 << 1 = 0010 转成十进制后就是 2
1<<4 实际就是 0001 << 4 = 10000 转成十进制后就是 16
|
是或运算符,也就是:00000001 | 00000010 | 00000100 = 00000111 = 4 + 2 + 1 = 7,
只要对应的二个二进位有一个为1时,结果位就为1
&
与运算符 ,也就是: 00000001 & 00000010 & 00000100 = 00000000 = 0,
只有对应的二个二进位都为1时,结果位才是1
主要就介绍这几个位运算符。
重点
枚举应用
一个NSUInteger类型,为什么能枚举出许多种类型?
1,2,4,8,16,32,64,128
我们设置推送类型属性赋值 NotificationType = 7
,那我们如何判断这个推送类型包含那些枚举呢?
我们要看看这个属性包含哪些选项,这时候只需要将 NotificationType 和某个选项进行 & 操作即可判断出属性是否包含这一选项。
if (types&UNNotificationPresentationOptionBadge){
//包含
}
types&UNNotificationPresentationOptionBadge相当于 00000111&00000001 的结果是00000001 = 1,if 判断为真,则types 包含 UNNotificationPresentationOptionBadge。
在我们的开发中,需要多个为枚举类型的属性匹配多个枚举项时,可以考虑上述方式。
多选列表应用
在我们的开发过程中,很多时候会遇到这种需求,一个支持单选和多选列表:
也可以利用位元算来实现
假如有默认项:
我们定义一个属性选中项 tokenType = 0
默认值为0;在列表处理时可以通过以下代码来判断:
NSInteger tempToken = 1 << indexPath.row;
if (self.tokenType & tempToken) {
//处理包含选项
}else{
//处理不包含选项
}
if (self.tokenType == 0 && indexPath.row == 0) {
//处理默认选项
}
在给列表项目赋值时,可以做以上操作。
在处理选择操作时可以通过以下代码处理:
NSInteger tempToken = 1 << indexPath.row;
if (self.tokenType & tempToken) {
self.tokenType = self.tokenType - tempToken;
}else{
self.tokenType = self.tokenType | tempToken;
}
if (tempToken == 1) {
self.tokenType = 0;
}
[tableView reloadData];//刷新列表
这样处理会让代码更加简洁,同时在处理结果的时候可以只处理一个 integer 就可以。
诸如此类,我们可以利用位运算处理很多开发中的问题。