ビット一括操作デモコード
フォーラムでnetbentonさんのcall関数を使わない投稿(下にリンクあり)を見て、ふと、自分が書いたビット操作のデモコード(callを使って関数を呼び、今はnetbentonさんのcall代替の方法)を思い出し、それを取り出してみんなにシェアして、初心者にちょっとした手助けができればと思います。
@echo off
title Bitwise example code by:cn-bathome-more
echo.
echo. Bitwise terminology explained (personal understanding):
echo.
echo.Bitwise operations: logical operations or bitwise shifts of binary numbers by the operands represented in the computer.
echo. with: all 1 is 1 (refers to the return value, the same below), otherwise it is 0.
echo.or: as long as there is 1, it is 1, otherwise it is 0.
echo.iso-or: different is 1, same is 0.
echo.Inverse: 1 is 0, 0 is 1 (monomial operator).
echo.negative: Inverse first and then add 1 (monomial operator).
echo.Shift left by n: equivalent to multiply by 2 to the nth power (with 0's complement).
echo.Shift right by n: Equivalent to dividing by 2 to the nth power (1's complement for negative numbers, 0's complement for positive numbers).
echo.
The following example is the result of running on a 32-bit system (value range: -2147483648~2147483647).
echo. Please enter the value (integer) that the batch can handle, otherwise it will not be processed correctly. If an overflow occurs, the result will not be correct either.
echo.
rem The function that converts decimal to binary.
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=Please enter two numbers (separated by a space):
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. The valid values of the two numbers entered are: "!num1!" and "!num2!", expressed in binary as:
set /a str1=num1,str2=num2
%fun_d2b:#a#=str1%
%fun_d2b:#a#=str2%
echo.&echo.!str1! ==^> !num1!
echo.!str2! ==^> !num2!
echo.&echo. The results of the various bitwise operations are as follows:
set /a "num=!num1!&!num2!,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> by bit with: !num1! ^& !num2! = !t!
set /a "num=!num1!|!num2!,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> by bit or: !num1! ^| !num2! = !t!
set /a "num=!num1!^^^!num2!,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> by bitwise iso or: !num1! ^^^^ !num2! = !t!
set /a "num=~!num1!,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> inverse by bit: ~(!num1!) = !t!
set /a "num=-!num1!,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> take negative: -(!num1!) = !t!
set /a "ran=%random%%%5+2,num=!num1!,num<<=ran,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> left shift!ran! bit: !num1! ^<^< !ran! = !t!
set /a "ran=%random%%%5+2,num=!num1!,num>>=ran,t=num"
%fun_d2b:#a#=num%&echo.&echo.!num! ==^> right shift!ran! bit: !num1! ^>^> !ran! = !t!
echo.&goto :agn
バッチ関数の効率的な代替アプリケーション(コールフリー!)。
高速リアルバッチ関数応用法!
サブプロセスへの呼び出しではなく・・・。
今度こそバッチプログラミングを新しい次元に引き上げるべきだと思うんです。
現在、1つのパラメータのみサポートされており
@echo off
::Define functions
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=)& amp;(for %%z in ("!hx!!xs:~%%2,1!!xs:~%%1,1!") do endlocal& set #a#=%%~z))"
::10 to hex function, parameter entry #a#
::To be defined before turning on variable delay
setlocal enabledelayedexpansion
for /l %%a in (1,7,1024) do (
set abc=%%a
(%d-h:#a#=abc%)
rem function call
echo !abc!
)
pause
複数のパラメータに対応できるようになりました
len関数を2つのパラメータに対応させました。
@echo off
::Define functions
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=)& amp;(for %%z in ("!hx!!xs:~%%2,1!!xs:~%%1,1!") do endlocal& set #a#=%%~z))"
::10 decimal to hexadecimal function, call method: %d-h:#a#=variable name%
set "len=for /f "tokens=1-3" %%1 in ("#a#") do setlocal enabledelayedexpansion&(if defined %%2 (set /a z=8180,x=0& amp;(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) "
::take the string length function, call method: %len:#a#=result variable name string variable name %
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 function calls
echo %%a to hex as:!abc! Number of characters before conversion:!slen! Number of characters after conversion:!dlen!
)
pause
発想が実に新しい
しかし、次の2つの理由から推奨されません。
コードの可読性が低下する
環境変数の使いすぎも効率に影響する
機能効率に関する問題
従来の "goto pair" は、よりシンプルで自由で効率的だと思う。
一般的に
組合せステートメント(ブラケットペアのステートメント)での関数の使用は避けるべきです。
もし、バランス的に、まだ
の場合、結合文のループ回数と再帰レベルが設計要件を満たしているか確認する必要があります。
この方法は、関数の内部構造については可読性に劣るが、メインプログラムの可読性については非常に良い性能を発揮する
ご覧ください。
(%len:#a#=slen abc%)
関数 len が呼び出され、変数 abc の文字列の長さを計算し、その結果を変数 slen に格納します。
関数を使う意味は、メインプログラムを簡略化することではありませんか?
また、関数については、過去の関数や自分がよく使う関数コードの参照であることが多いので、コメントに従って使えばよいでしょう。
その関数が内部で何をやっているのか、わざわざ気にする必要もないでしょう。他のプログラミング言語でapiやdosの割り込みを呼び出すようなもので、内部で何が起こっているのか知る必要はないのでは?
このような関数があれば、バッチ処理の初心者でも簡単に効率的なバッチを書くことができますね。
これらは、ベテランがより大きなバッチプログラムを書きたいときでも、大きな煉瓦となる。
この関数定義はたった1行でできます。欠点は変数名と環境変数のスペースを取ることですが、これは効率を考えると微々たるものです。なぜなら :sub サブプロシージャの呼び出しは30階層もかかり、set var=n の300回の実行はもちろん、ポイントがあり、この使い方だと :sub バッチの内部サブルーチンを呼ぶより半分は速いですが、それでも %len:#a#=var% を使うより時間がかかりますから効率性は想像できますね。
関数のこのようなカプセル化した後、それはトークン%%aのための同じの使用にメインプログラム、len関数、メインプログラムと関数の4階の構造を破ることは不可能ですが、同じは、正しい結果を得ることができます。関数内の変数の使用は完全に一時的なもので、関数の終わりにendlocalでクリアされ、戻り値の結果のみを保存しています。
褒めたいことがあるんです、なかなか言いにくいんですが。ある創作で、ふとnetbentonのような関数の使い方を思い出したので、私も真似してみました、へへへ。確かに、オーナーの言うように、バッチ処理の機能を十分に拡張できるような、効率的で正しい、よく使われる関数を開発して、より高機能を積み重ねることで、より高い飛躍を実現することが必要ですね。
コマンドの繰り返し呼び出しに対応する方法・技術については、いくつかあるようです。
1. コピー&ペーストの繰り返し このパターンは、実行タスクやコマンドが比較的少ない場合に使えます。例えば、echoを使って2~3行の空行を生成するのは、forを使って費用対効果の高いものを生成するより良いのではないでしょうか? このパターンの結果、重複したコードが多くなり、効率も悪くなります。
2. タグ、GOTOジャンプを使う。最も基本的なパターンは、同じ関数セグメントを何度も使うコードからタグを作り、gotoを使ってジャンプすることです。しかし、gotoはあくまでジャンプアウトの役割であり、ジャンプバックの役割ではないので、コードを自動的に戻したい場合は、再度ジャンプする必要があります。
3.タグを使用して、callを呼び出す。callの利点は、他のタグにジャンプした後、自動的にジャンプバックできることである。なぜ自動的にジャンプバックできるかというと、callは元のコードの後にタグを使うので、元のプロセスを中断するためにメモリストレージを多く使用する可能性があるからです。そのため、比較的遅く感じられるでしょう。しかし、callは引数のサポートが充実しているので、手放せなくなるのです。
4. FORコマンドを使ってシンプルにする。FORの特徴に合ったコマンドをFORに組み込むことで、必要な繰り返し操作を減らすことができます。
5、変数を拡張するために関数を使用する。特定の変数にいくつかのコマンドの組み合わせを割り当てて、パラメータをサポートする汎用関数に変えると、ラベルを再作成する必要はありませんが、変数のスペースを占有します。このモードは、割り当てられたコマンドの組み合わせが短く、あまりスペースをとらない変数関数に適しています。また、異なるバッチプログラムで使用するために、簡単にラップすることができます。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン