![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-08-12 02:34 |
共 47,811 主题排行 / 349,897 发帖 / 今日 0 篇 / 48,256 会员排行 |
| DOS批处理 & 脚本技术(批处理室) » [求助]代码解释 |
| 可打印版本 3,604 / 16 |
| 第1楼 ZJHJ | 发表于 2010-08-18 00:29 |
| 高级用户 发帖 374 积分 609 | |
|
[求助]代码解释 我看到如下代码,非常精辟!求老师指点!
@echo off&setlocal enabledelayedexpansion :: 代码5 :: Code by CN-DOS terse set "hx=0123456789ABCDEF" set/p str=: for /l %%i in (1 1 8) do ( if !str! GTR 0 ( set/a "n=str&15,str>>=4" call set h=%%hx:~!n!,1%%!h! ) ) if not defined h set "h=0" echo.%str% 的十六进制为:0x!h! pause 1, %%i 是从1取到8,为什么?却没有看到%%i 的去处? 2, set/a "n=str&15,str>>=4" 是取余的意思,但怎么也看不懂..... 如果按我的写法却成了这样: set /a y= str%%16 set /a ya=str/16%%16 set /a yb=str/256%%16 set /a yc=str/4096%%16 set /a yd=str/65536%%16 set /a ye=str/1048576%%16 set /a yf=str/16777216%%16 set /a yg=str/268435456%%16 set m=0123456789ABCDEF set cdm=!m:~%yg%,1!!m:~%yf%,1!!m:~%ye%,1!!m:~%yd%,1!!m:~%yc%,1!!m:~%yb%,1!!m:~%ya%,1!!m:~%y%,1! [ Last edited by ZJHJ on 2010-8-18 at 00:36 ] |
|
| 第2楼 slore | 发表于 2010-08-18 13:00 |
| 铂金会员 发帖 2,478 积分 5,212 | |
|
那个循环只是控制循环次数为8次
主要是移位操作。。。具体含义可以google下相关位操作, 与运算,左移,右移 |
|
| 第3楼 HAT | 发表于 2010-08-18 17:40 |
| 版主 发帖 5,017 积分 9,023 | |
|
批处理位运算以及原码、反码、补码的概念
http://bbs.bathome.net/thread-1844-1-1.html |
|
| 第4楼 q8249014 | 发表于 2010-08-20 11:10 |
| 初级用户 发帖 45 积分 175 | |
|
这段代码是我学习帖①中的一段实例演示代码,是我精简和修正过的
1。2147483647 的十六进制为:0x7FFFFFFF set /a 的极限 [2^31-1] 7FFFFFFF=8位 所以我们最多循环8次就可以啦 for只是为了循环 %%i只是语法的需要 所以…… 2。参考位运算的帖子 |
|
| 第5楼 doshsyy | 发表于 2010-08-20 19:00 |
| 新手上路 发帖 15 积分 19 | |
|
i只是控制循环次数为8次。
set/a "n=str&15,str>>=4" n=str&15相当于C语言中的n=str%16,str&15中15二进制位1111,str的二进制与1111进行“&“即"与"运算,只取str二进制的最后四位,即str/ 16的余数。例如:30&16-->00011110&1111=1110=14。即相当于30%16=14。 str>>4,str二进制右移四位,即丢失最后四位,相当于str=str/16然后取整,即C语言中的int str=str/16。 本来写的很详细的,但是说不让发。所以辛辛苦苦编辑的内容丢失了,只能简单点了。如果要怪,就怪论坛非得注册两个小时才可发言!(好像我注册了不止2个小时了,最后只能到命令行发帖,无语!) [ Last edited by doshsyy on 2010-8-20 at 21:12 ] |
|
| 第6楼 doshsyy | 发表于 2010-08-20 19:03 |
| 新手上路 发帖 15 积分 19 | |
|
我倒是觉得call set h=%%hx:~!n!,1%%!h!更难懂。为什么要加call,不加call为什么不对?
[ Last edited by doshsyy on 2010-8-23 at 13:41 ] |
|
| 第7楼 ZJHJ | 发表于 2010-08-20 23:39 |
| 高级用户 发帖 374 积分 609 | |
|
这个 set/a "n=str&15,str>>=4" 还是难懂....
我觉得如果从原理学习的角度来理解,将代码写成这样就非常容易理解了: @echo off setlocal enabledelayedexpansion set /p qw=输入十进制数字(极限值2147483647) set m=0123456789ABCDEF set /a y=qw, ys=qw%%16 set h=!m:~%ys%,1! for /l %%i in (1 1 7) do ( set /a y=!y!/16, ys=!y!/16%%16 call set h=%%m:~!ys!,1%%!h! ) :ie if %h:~0,1%==0 ( set h=%h:~1% goto ie ) echo %qw% 的十六进制为 !h! pause [ Last edited by ZJHJ on 2010-8-21 at 00:45 ] |
|
| 第8楼 doshsyy | 发表于 2010-08-21 07:54 |
| 新手上路 发帖 15 积分 19 | |
|
恩,是难懂,但是代码简洁,并且调用的是系统的基本运算符,速度也快。这是批处理的运算符号的常用技巧。
|
|
| 第9楼 hsyy | 发表于 2010-08-21 08:05 |
| 新手上路 发帖 2 积分 6 | |
|
我想测试下论坛的bug。 我想测试下论坛的bug。果然有,不过不是严重,不威胁安全。
[ Last edited by hsyy on 2010-8-21 at 08:07 ] |
|
| 第10楼 ZJHJ | 发表于 2010-08-23 12:39 |
| 高级用户 发帖 374 积分 609 | |
|
如果把程序的效率看的很重要的话,我不认同代码简单效率就高。
我也做过试验: 连续处理1万组随机9位数,转化为十六进制。 如果用直显方式需要5分20秒 如果用 for /l %%i in (1 1 8) do ( if !str! GTR 0 ( set/a "n=str&15,str>>=4" call set h=%%hx:~!n!,1%%!h! ) ) 用时约 13分15秒 如果用 :dycx set /a y=qw, ys=qw%%16 set h=!m:~%ys%,1! :bb set /a y=!y!/16, ys=!y!/16%%16 call set h=%%m:~!ys!,1%%!h! if !y! GTR 0 goto bb 用时约 22分37秒 |
|
| 第11楼 slore | 发表于 2010-08-23 12:59 |
| 铂金会员 发帖 2,478 积分 5,212 | |
|
这个不是因为代码简单。。。位运算正好简单罢了……
理论上位运算速度快,所以代码用位操作。 是为了效率用位运算,不是因为位操作代码简洁。。。。 bat的解释执行不是我们能控制的,如果是高级语言绝对是位运算快。 这里还牵扯到字符串。。。 10楼的直接显示什么意思?直接echo没转换么? 看你的数据貌似用set/a "n=str&15,str>>=4"快8,9分钟? 但是和你说的 如果把程序的效率看的很重要的话,我不认同代码简单效率就高。 又不相符。。。。 |
|
| 第12楼 doshsyy | 发表于 2010-08-23 13:53 |
| 新手上路 发帖 15 积分 19 | |
|
我没说代码简洁就会执行的效率高,我倒不会这么无知。要说代码质量,要考虑时间复杂度和储存空间需求,对小程序来说没有什么必要去考虑。对于大型程序来说是绝对有必要。对于上面的程序只是刚好可以用执行效率高的二进制位的逻辑运算与移位运算而且代码简洁。所以我才说“但是代码简洁,并且调用的是系统的基本运算符,速度也快。”,不知道你为什么说我说过代码简洁执行效率就高?还有,对于你得到的“直显方式”效率比直接的二进制执行效率高的结果我感到疑惑!
|
|
| 第13楼 doshsyy | 发表于 2010-08-23 15:18 |
| 新手上路 发帖 15 积分 19 | |
|
@echo off&setlocal enabledelayedexpansion
set t1=!time! echo %t1% for /L %%i in (1 1 10000) do ( set /A str=!random! set s=!str! set hx=0123456789ABCDEF for /L %%j in (1 1 8) do ( if !str! GTR 0 ( set /A "n=!str!&15,str>>=4" call set h=%%hx:~!n!,1%%!h! ) ) if not defined h set "h=0" echo.!s! 的十六进制为:0x!h! set h= ) set t2=!time! echo %t2% for /F "tokens=2,3delims=:" %%i in ("%t1%") do ( set t1m=%%i set t1s=%%j set t1s=!t1s:~0,-3! ) echo %t1m% !t1s! for /F "tokens=2,3delims=:" %%i in ("%t2%") do ( set t2m=%%i set t2s=%%j set t2s=!t2s:~0,-3! ) echo %t2m% !t2s! set /A "tm=%t2m%-%t1m%,ts=!t2s!-!t1s!" echo %tm%:%ts% pause 回显 1:2(1分02秒) @echo off&setlocal enabledelayedexpansion set t1=!time! for /L %%i in (1 1 10000) do ( set /A str=!random! set s=!str! set hx=0123456789ABCDEF for /L %%j in (1 1 8) do ( if !str! GTR 0 ( set /A "n=!str!&15,str>>=4" call set h=%%hx:~!n!,1%%!h! ) ) if not defined h set "h=0" echo !s!的十六进制为:0x!h! set h= ) set t2=!time! for /F "tokens=2,3delims=:" %%i in ("%t1%") do ( set t1m=%%i set t1s=%%j set t1s=!t1s:~0,-3! ) for /F "tokens=2,3delims=:" %%i in ("%t2%") do ( set t2m=%%i set t2s=%%j set t2s=!t2s:~0,-3! ) set /A "tm=%t2m%-%t1m%,ts=!t2s!-!t1s!" echo %tm%:%ts% pause 回显 1:1(1分01秒) 不知道10楼你怎么弄的,运行时间那么长,而且差距那么大,估计代码写错了吧! |
|
| 第14楼 ZJHJ | 发表于 2010-08-23 19:04 |
| 高级用户 发帖 374 积分 609 | |
|
我的意思是说:
如果用for /l %%i in (1 1 8) do ( if !str! GTR 0 ( set/a "n=str&15,str>>=4" call set h=%%hx:~!n!,1%%!h! ) ) 或者用 for /l %%i in (1 1 7) do ( set /a y=!y!/16, ys=!y!/16%%16 call set h=%%m:~!ys!,1%%!h! ) 的方式,即for循环代码都很简单,但是处理速度并不快。用时约 13分15秒 如果用 :bb set /a y=!y!/16, ys=!y!/16%%16 call set h=%%m:~!ys!,1%%!h! if !y! GTR 0 goto bb 方式处理,代码也很简单,但是处理速度却最慢。用时约 22分37秒 如果用 set /a y= qw%%16 set /a y1=qw/16%%16 set /a y2=qw/256%%16 set /a y3=qw/4096%%16 set /a y4=qw/65536%%16 set /a y5=qw/1048576%%16 set /a y6=qw/16777216%%16 set /a y7=qw/268435456%%16 set h=!m:~%y7%,1!!m:~%y6%,1!!m:~%y5%,1!!m:~%y4%,1!!m:~%y3%,1!!m:~%y2%,1!!m:~%y1%,1!!m:~%y%,1! 的方式是最快的,需要5分20秒 问题出在for或goto [ Last edited by ZJHJ on 2010-8-23 at 19:08 ] 附件 代码比较.rar (44.8 KiB) |
|
| 第15楼 HAT | 发表于 2010-08-24 11:18 |
| 版主 发帖 5,017 积分 9,023 | |
|
Re 6 楼 变量延迟扩展和变量嵌套的基础知识
|
|
| 1 2 下一页 |
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |