免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1751 | 回复: 5
打印 上一主题 下一主题

[数值计算] 问验证数字进制的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-08-03 16:25 |只看该作者 |倒序浏览
下面两端是arch安装脚本里,大意估计是遇到\100之类的转义,拿后面三个去做验证。

valid_number_of_base() {
  local base=$1 len=${#2} i=

  for (( i = 0; i < len; i++ )); do
    (( (${2:i:1} & ~(base - 1)) == 0 )) || return
  done
}

if valid_number_of_base 8 "${1:i+1:3}" || valid_number_of_base 16 "${1:i+1:3}"; then

我有两个问题

1. 为什么要 ~(base - 1) ,而不是直接base呢?

2. 我觉得这个函数验证不出16进制的吧? 比如 w & 16  这个还是0阿



论坛徽章:
0
2 [报告]
发表于 2012-08-03 16:57 |只看该作者
本帖最后由 personball 于 2012-08-03 17:28 编辑

回复 1# riptide2012


    都写了是和base-1进行& 运算。。你16进制还和16去&??
等贫道再仔细算算

首先明确下符号含义:
&  位运算之  与         
~ 位运算之  取反   
优先级 ~ 大于 &


先看一下~运算,位的正负数表示
比如 ~7  ,  
7的二进制表示为   0        000000...000 0111  
第一个符号位(暂时就按0表示正数来看),中间N多个0取决于整体有多少位(比如int可以最多16位也可以32位,取决系统和具体的环境吧,先不管)
echo $((~7)) 可以得到结果 -8
-8的二进制表示为   1       111111...111 1000
相应的给个正数8的二进制表示参考   0         000000...000  1000
对齐一下看看
0    00000...000 0111    #7
1    11111...111 1000    #~7  即 -8
0    00000...000 1000    #8

来个比8小的数字,比如6
0    00000...000 0110    #6
跟 ~7 进行 与 运算
1    11111...111 1000    #~7 即-8
与运算,结果明显为0,
来个比8大的数字,比如10
0    00000...000 1010    #10
与运算,对齐了自己看,结果为8

直接拿字母来进行 &~ 运算的话,估计都被当成0了,16进制的情况,要加上0x标记,可以试试在bash命令上 echo $((0xa&~15))

差不多这样了,可能底层实现有差异,大概的理论记得学校里就这么教的。


论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
3 [报告]
发表于 2012-08-03 17:19 |只看该作者
因为有个数字叫0

论坛徽章:
0
4 [报告]
发表于 2012-08-03 17:35 |只看该作者
其实简单点讲,以8进制为例
8进制的字符表示是 0到7,即8进制各个位上不会看到比7大的数字,这个数字暂记为N
而通过按位执行 N &~7,只要N是小于等于7,通过&~(取反后求与)得到的值恒为0(二进制表示的左边一长串的1,和一串的0求与,~7的右边三位都是0)
而比7大的,由于右向左第四位开始两个01串同时有1,所以得到的肯定为非0
据此,确认N是否符合   表示8进制的合法数字字符什么的。。

论坛徽章:
0
5 [报告]
发表于 2012-08-03 17:50 |只看该作者

我不知道为什么要 ~(base - 1), 这个看起来像要求一个正数的负数补码。

但这里的判断都一位字符一位字符来的。也就是说都是正数。八进制来说  9 & 8 = 8

0000 1001
0000 1000
--------------
0000 1000

完全一样的效果阿

论坛徽章:
0
6 [报告]
发表于 2012-08-03 17:52 |只看该作者
直接拿字母来进行 &~ 运算的话,估计都被当成0了,16进制的情况,要加上0x标记,可以试试在bash命令上 echo $((0xa&~15))
--------------------------------------------------------------------------------------------------------------------------

这个就是我二个问题的思路。 代码里没有 Ox"var" 那16进制判断不是摆设么?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP