powを書いてみましょう。まずバイナリ法をgotoを使って書きます。
@echo off call :pow 2 1024 3 exit /b 0 :pow setlocal set /a m = 1 set /a p = %1 set /a e = %2 :loop_pow if %e% == 0 exit /b %m% set /a r = %e% %% 2 if !r! == 1 set /a m = %m% * %p% %% %3 set /a p = %p% * %p% %% %3 set /a e /= 2 goto :loop_pow
これをforを使って書きます。eが0になればexitで抜ければいいので、回す回数はべき乗と同じとします。
setlocal enabledelayedexpansion … :pow setlocal set /a m = 1 set /a p = %1 set /a e = %2 for /L %%i in (1, 1, %2) do ( if !e! == 0 exit /b !m! set /a r = !e! %% 2 if !r! == 1 set /a m = !m! * !p! %% %3 set /a p = !p! * !p! %% %3 set /a e /= 2 )
遅くなっているんですが。こう変えると、
for /L %%i in (1, 1, 100) do (
あ、速くなりましたね。どうやら指定した回数必ず回すようです。echo onにしてみるとわかります。
@echo on for /L %%k in (1, 1, 5) do ( if %%k == 2 exit /b %%k )
バッチファイルなら指数は32ビット符号付き整数なので32回回せば十分です。
:pow setlocal set /a m = 1 set /a p = %1 set /a e = %2 for /L %%i in (1, 1, 32) do ( if !e! == 0 exit /b !m! set /a r = !e! %% 2 if !r! == 1 set /a m = !m! * !p! %% %3 set /a p = !p! * !p! %% %3 set /a e /= 2 )
回す回数を減らす方法もありますが、多くの場合はその必要はありません。例えば1から100万までのべき乗を求めるなら21回回せば十分です。数回で済むこともありますが、多くは20回程度必要になって数回しか必要のない場合はごくわずかです。