#### 批处理位运算演示代码

```@echo off
title 位运算示例   code by:cn-bathome-more
echo.
echo.位运算名词解释(个人理解):
echo.
echo.位运算: 按操作数在计算机内表示的二进制数逐位进行逻辑运算或移位运算.
echo.与:   全部都是1才为1(指返回值,下同),否则为0.
echo.或:   只要有1则为1,否则为0.
echo.异或: 不同为1,相同为0.
echo.取反: 是1则0,是0则1(单目运算符).
echo.取负: 先取反再加1(单目运算符).
echo.左移n位: 相当于乘以2的n次方(用0补位).
echo.右移n位: 相当于除以2的n次方(负数用1补位,正数用0补位).
echo.
echo.下面的示例是在三十二位系统(数值范围:-2147483648~2147483647)下运行的结果.
echo.请输入批处理能处理的数值(整数),否则将不能正确处理.如发生溢出,结果也不会正确.
echo.
rem 将十进制转换为二进制的函数.
set "fun_d2b=setlocal enabledelayedexpansion&(for /l %%a in (0 1 31) do (set /a "str=!#a#!^>^>%%a"&set /a "str^&=1"&set "str_d2b=!str!!str_d2b!"))&(for %%a in (!str_d2b!) do (endlocal&set #a#=%%a))"
setlocal enabledelayedexpansion
:agn
set in=&set /p in=请输入两个数(中间用空格隔开):
if not defined in exit
set n=0
for %%a in (%in%) do (
set /a n+=1
set /a num!n!=%%a 2>nul
)
cls
echo.输入的两个数的有效数值为: "!num1!" 和 "!num2!", 用二进制表示分别为:
set /a str1=num1,str2=num2
%fun_d2b:#a#=str1%
%fun_d2b:#a#=str2%
echo.&echo.!str1!  ==^> !num1!
echo.!str2!  ==^> !num2!
echo.&echo.各种位运算的结果如下:
set /a "num=!num1!&!num2!,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> 按位与:   !num1! ^& !num2! = !t!
set /a "num=!num1!|!num2!,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> 按位或:   !num1! ^| !num2! = !t!
set /a "num=!num1!^^!num2!,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> 按位异或: !num1! ^^^^ !num2! = !t!
set /a "num=~!num1!,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> 按位取反:    ~(!num1!) = !t!
set /a "num=-!num1!,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> 取负:        -(!num1!) = !t!
set /a "ran=%random%%%5+2,num=!num1!,num<<=ran,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> 左移!ran!位:   !num1! ^<^< !ran! = !t!
set /a "ran=%random%%%5+2,num=!num1!,num>>=ran,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> 右移!ran!位:   !num1! ^>^> !ran! = !t!
echo.&goto :agn```

### 批处理函数的高效另类应用（免call的哦！）

```@echo off
::定义函数
set "d-h=setlocal enabledelayedexpansion&set/a dx=#a#&set xs=0123456789abcdef&(for /l %%z in (1,1,4) do set /a x%%z=dx%%16,dx=dx/16)&(for /f "tokens=1-4" %%1 in ("!x1! !x2! !x3! !x4!") do set hx=!xs:~%%4,1!!xs:~%%3,1!&(if !hx!==00 set hx=)&(for %%z in ("!hx!!xs:~%%2,1!!xs:~%%1,1!") do endlocal&set #a#=%%~z))"
::10进制转为16进制的函数,参数入口#a#
::要在开启变量延迟之前定义
setlocal enabledelayedexpansion
for /l %%a in (1,7,1024) do (
set abc=%%a

(%d-h:#a#=abc%)
rem 函数调用

echo !abc!
)
pause```

len函数为两个参数，

```@echo off

::定义函数
set "d-h=setlocal enabledelayedexpansion&set/a dx=#a#&set xs=0123456789abcdef&(for /l %%z in (1,1,4) do set /a x%%z=dx%%16,dx=dx/16)&(for /f "tokens=1-4" %%1 in ("!x1! !x2! !x3! !x4!") do set hx=!xs:~%%4,1!!xs:~%%3,1!&(if !hx!==00 set hx=)&(for %%z in ("!hx!!xs:~%%2,1!!xs:~%%1,1!") do endlocal&set #a#=%%~z))"
::10进制转为16进制的函数,调用方法：%d-h:#a#=变量名%

set "len=for /f "tokens=1-3" %%1 in ("#a#") do setlocal enabledelayedexpansion&(if defined %%2 (set /a z=8180,x=0&(for /l %%a in (1,1,14) do set/a "y=(z-x)/2+x"&(for %%b in (!y!) do if "!%%2:~%%b,1!" equ "" (set/a z=y) else (set/a x=y)))) else (set z=0))&(for %%z in ("!z!") do endlocal&set %%1=%%~z)"
::取字符串长度函数，调用方法：%len:#a#=结果变量名 字符串变量名%
setlocal enabledelayedexpansion

for /l %%a in (1,7,1024) do (
set abc=%%a

(%len:#a#=slen abc%)
(%d-h:#a#=abc%)
(%len:#a#=dlen abc%)
rem 函数调用

echo %%a转成16进制为：!abc!   转换前字符数:!slen!  转换后字符数:!dlen!
)
pause```

(%len:#a#=slen abc%)

1、复制粘贴，重复出现。这种模式在执行任务与命令比较少的情况下可以使用，比如使用echo产生两三行空行，总比使用for产生的划算吧？这种模式的结果是造成大量重复代码，缺乏效率。
2、使用标签，GOTO跳转。把那些反复使用的同一功能段的代码做成一个标签，然后使用goto跳转，这是最基本的模式。但goto只负责跳出去而不跳回来，要想代码自动回来则需要再跳一次。
3、使用标签，Call调用。call的好处是跳到其他标签后能够自动跳回来。之所以能够自动跳回来，因为call在原来代码后面使用了标记，可能使用了更多的内存存储来暂停原来的进程。所以，相对而言，会显得较慢一些。但Call对参数有很好的支持，使得人们对其无法割舍。
4、使用FOR命令，化繁为简。将那些符合FOR特性的命令融合到FOR当中，即可减少必要的重复操作。
5、使用函数，扩大变量。将一些命令组合赋值到某一个特定的变量中，变成通用函数，支持参数，它不需要重新建立标签，但它占据了一个变量空间。这种模式适用于所赋值的命令组合比较简短，占用空间不大的变量函数中。可以方便封装以用于不同的批处理程序中。