ascii码_umask,补码,ASCII码:稍微深入考虑一点

1. umask
豆瓣网友指出,微信读书有个好处,就是能看到别人的标注和笔记,别人也能看到自己的。kindle也能共享,但是远没有微信方便和活跃。我就偷偷看别人的笔记,比如大家读古龙时候的感叹。有时猜测,这位读者是个孩子,那位读者觉得自己不是孩子了。有时自己也感叹,哇,当年没有读懂,或者当年肯定读不懂。有时还参与两句。
也看娄嘉鹏老师的技术笔记,他的很多阅读不是为了学习,而是考虑在教学中如何清晰讲解,比如下面这条就挺有意思。
娄老师标注的是文字原文是这样的,"特别强调一下,网络上有很多关于计算umask遮罩后权限值的讲解,比较主流但是错误的讲解方式是使用“同位相减”的做法来计算遮罩后的值"。
"特别强调一下",WJY同学表达过,这是相当有脾气的说法。作者的意思是"就这你还不明白?我还得再说一遍。"对这句话,教师当慎言。

c673662afad34d2bf4328142fab7a375.png

(1)
后面作者提到了错误的看法,还举了例子。用 权限666 减去 掩码011,同位相减得到权限值 655。这个结果是错的,正确的权限值是 666。
为啥正确呢,不知道。作者没有给出正确的算法。教学中教师通常容易犯的错误是只把正确的说了,但是(既不说原理,也)不说哪些是错的。比如深蹲时双脚就像旋入地面,原理是绷紧下肢提高对膝盖的控制,尤其是最低端,对应的错误是大腿 (内侧?) 放松。教练就说,旋进地面啊,拳要打进去,站直,你怎么连什么是站直也不会,不是超伸。好,终于说到了什么是不对的。
正确的权限值是 666,这可以通过实验验证,但是原理还是不清楚。
作者说,权限666 和 掩码011 间的运算,当作按位减是不对的,那么什么是对的呢?对这个算法的描述,作者用的动词是"遮罩掉"。遮罩就是掩码mask。但是,"遮罩掉"是个什么操作,难度不 (显然) 是按位减么?作者定义了个名词,但是没有解释。
上网搜索一下,比如[https://www.cnblogs.com/wish123/p/7073114.html]在《Linux中设置UMASK值》这篇博客用的动词是,从最大权限777中"去掉"umask值。
遮罩掉、去掉,有同学说,不是挺明白的么?
(2)
什么是明白?就是能编程序实现。C语言里有定义遮罩掉、去掉这两个函数或操作符么。你是不是又想做按位减法了。
对了,娄老师标记这段话时,是怎么评论的呢?他说,"一般与掩码与,umask取反与"。我最初没看明白,但是娄老师这句话显然比作者更靠谱,至少 与、取反这样的术语,比"遮罩掉、去掉"更接近机器的语言。在靠谱这个意义上,不说遮罩掉、去掉这样的人话,更像是做人事。
我没问娄老师到底啥意思,又不急着知道,觉得自己想想挺好玩的。
事实上,我能体会到 遮罩掉、去掉 的含义,也就是说,我可以枚举/穷举出所有的结果,而且这本书里有例子可以验证。于是我打了个表格,以下第一列p代表 privilege权限,第二列是umask,第三列是求出的结果。

|P | umask | r ||0 |  0    | 0 ||0 |  1    | 0 ||1 |  0    | 1 ||1 |  1    | 0 |


看第三010行,确实不是按位减。这一位,也就是作者举的 666 去掉 011 以后 得 666,而不是 655,6或5转换成二进制为110和101的最后一bit。
有个这个表格,我们可以写一大堆if-else……了。
(3)
不优雅啊,我估计RH和GYB同学会这么说。
离散数学课和数字电路课上,我们学过把真值表转换成逻辑表达式。过程略过,结果是

 r = p & !umask


这说我想起了娄老师说的话,"umask取反与",umask取反,然后与p。

3e6bd97d44275cad938ae61b674b5d9e.png

2. 补码
什么时候用补码?负整数在计算机中用补码表示。
为什么需要补码?通过补码,CPU可以使用加法器做减法计算。
怎么算补码?反码加1。
为什么?
那些天同时在看这本书,[https://book.douban.com/subject/25882201/],From Mathematics to Generic Programming。看到补码运算的时候写了一段笔记,简单解释补码计算的原理。
(1)补码
补码是什么?

补码 = 模 - 数 ..................公式1


模是什么?模是进制的大小。钟表12进制,模就是12。人类用10进制,模是10。
模12的例子:

(-3) = 12 - 3 = 9   ;9点是差3个小时12点(-2) = 12 - 2 = 10  ;10点是差2个小时12点


模10的例子:

-2 = 10 - 2 = 8


模8的例子:

-2 = 8 - 2 = 6


对上述例子中的最后一个,模8中的-2,我们验证一下。
二进制下2取反+1,

(010)-> 取反 -> (101) -> +1 -> (110)-2   ->->->->->->->->->->->->->   6


(2)取反

取反操作 <=> (模-1)-数    ............公式2

这是因为 数+反 = 模-1
看两个例子

  001+ 110------  111  010+ 101------  111


(3)推导

取反     <=> (模-1) - 数         ..........根据公式2取反 + 1 <=> (模-1) - 数 + 1     ..........左右都加1取反 + 1 <=>  模    - 数         .......... -1+1 => 0取反 + 1 <=>  补码               .......... 公式1


所以"取反+1"就是补码。

228b2735e0cf2c3d96936687e9fb9e98.png

(4)原理
基于的原理是 : 模 就是 0。
12点就是0点,毕十10就是零蛋。限制位数,0x100,就是 0x00。
更深层的原理是因为 : 求余,求模。
这就是为什么求余运算的名字是求模的原因吧。
(5)编码举例
除去符号位 (假设模8) ,以下每行的两个数字编码相同。

| +0 | -0 || 1  | -7 || 2  | -6 || 3  | -5 || 4  | -4 || 5  | -3 || 6  | -2 || 7  | -1 |


每行的两个数字,它们绝对值的和是8,即模。
举例,-7的补码是

  原码        111,  按位取反得到 000,  加1得到     001.


刚好与同一行的 1 的原码 001 相同。
我们还能注意,负数里面还有个 -0。

c2195b1b71951bc40f384e8dc101a309.png

3. ASCII
这段非常短,就是想回答下不少同学可能有过的疑惑,ASCII里为什么 A是65,a是97,这么有零有整的。不怎么好记啊。
因为,如果你不看两列的ASCII码表,而是找一下16行16列的ASCII码表就会发现,或者按十六进制就会发现,就像1024是整数,'A'和'a'都是整数。
A 是 0x41,即4*16+1 = 65;
a 是 0x61,即6*16+1 = 97。
还有'0',是0x30,即 48。

0b01057de0d929ec378f9da2bf175963.png

为什么ASCII要在大写、小写、数字之间加些乱七八糟的字符,逗号、冒号、方括号,还不把这些符号连续地放在一起。正是为了填充,让A、a、0在整数开头吧。

90b81b22ec52675663d31e1052d6ddd9.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值