【コマンドプロンプト】32bit以上の計算をする方法(引き算)
公開日:
:
コマンドプロンプト 32bit以上の計算, cmd, set /a, setコマンド最大値
コマンドプロンプトで計算するときに「Set /a ~」で計算式を使うと符号付32bitの間でしか計算ができない。
符号付32bitの範囲は「-2147483648 ~ 2147483647」であるため、この範囲の値でないと「Set /a ~」と入力した際にエラーとなるか、オーバーフローを起こし、正しい計算が行われない。
たとえば「2147483647 + 1」は「2147483648」になるはずだが「Set /a」で実行すると
下記の画像のように、「-2147483648」となってしまう。
また、「Setコマンド」で「2147483647」を超える値をセットすると
「無効な数字です。数値は 32 ビットで表記される数値です。」と表示されエラーとなる
ということで、32bitを超える計算(引き算)を行う為にバッチを組んでみた。
正直、ものすごく強引だが、引き算はできた。
問題は使い道がいまいち無いという。。。。
@echo off
setlocal enabledelayedexpansion
REM #################################################################
REM
REM コマンドプロンプトで32bitを越える引き算処理
REM
REM ※AがBを上回っていること。
REM
REM #################################################################
REM A-Bの値をセット
Set A=123456789101112
Set B=123451230568153
REM ==============================================================
REM 文字列カウント&一文字ずつ変数に格納処理
REM ==============================================================
REM -----------------------------------
REM Aの文字数カウント
REM -----------------------------------
call :strlen "%A%"
REM A文字数保存
set /a Acnt=%strlen%
REM -----------------------------------
REM Aを一文字ずつ配列に格納
REM -----------------------------------
call :DataArrStored A %Acnt%
REM -----------------------------------
REM Bの文字数カウント
REM -----------------------------------
call :strlen "%B%"
REM B文字数保存
set /a Bcnt=%strlen%
REM -----------------------------------
REM Bを一文字ずつ配列に格納
REM -----------------------------------
call :DataArrStored B %Bcnt%
REM ==============================================================
REM 計算処理(引き算)
REM ==============================================================
REM -----------------------------------
REM 計算処理
REM -----------------------------------
call :subtraction
REM -----------------------------------
REM 結果(result[i])を結合処理
REM -----------------------------------
REM iにAの文字数を代入
set /a i=%Acnt%
REM 配列から結果へ一文字(一番大きい位)を代入
set result=!result[%i%]!
:result_join
REM 配列が存在しない場合はループを抜ける
if "!result[%i%]!"=="" goto next1
REM 配列の添え字のカウントダウン
set /a i=%i%-1
REM 1文字結合
set result=%result%!result[%i%]!
goto result_join
:next1
REM -----------------------------------
REM %result%の先頭文字に「0」がある場合、除去
REM -----------------------------------
REM iの初期化
set /a i=-1
REM Aの文字数-1を代入
set /a tempAcnt=%Acnt%-1
:Zero_Del_Loop
set /a i=%i%+1
REM Aの文字数を超える場合(計算結果が0)
if %i% GTR %tempAcnt% goto next2
REM 先頭文字から比較し、0である場合、ループ
if "!result:~%i%,1%!"=="0" goto Zero_Del_Loop
:next2
REM 計算結果が全て0か
if "%i%" EQU "%Acnt%" (
REM 結果に0を代入
set result=0
REM それ以外
) else (
REM 先頭から0を除く
set result=!result:~%i%!
)
REM -----------------------------------
REM 結果(result)出力
REM -----------------------------------
echo A:%A% - B:%B%
echo.
echo 結果:%result%
pause
exit /b
REM #################################################################
REM
REM サブルーチン
REM
REM
REM
REM #################################################################
:strlen
REM ==================================================
REM 文字数カウント
REM ==================================================
set strlen_string=%~1
set strlen=0
if "%strlen_string%"=="" goto :EOF
:strlen_while
call set ch=%%strlen_string:~%strlen%,1%%
if "%ch%"=="" goto strlen_wend
set /a strlen+=1
goto strlen_while
:strlen_wend
goto :EOF
:DataArrStored
REM ==================================================
REM 一文字ずつ配列として格納
REM ==================================================
set Arr=%1
set /a cnt=%2
set /a i=1
set /a cnt=%cnt%-1
:DataArrStored_loop
if %i% GTR !%Arr%cnt! goto :EOF
set %Arr%[%i%]=!%Arr%:~%cnt%,1!
set /a cnt=%cnt%-1
set /a i=%i%+1
goto DataArrStored_loop
goto :EOF
:subtraction
REM ==================================================
REM AとBの引き算
REM ==================================================
set /a i=1
:subtraction_loop
REM A配列の要素数を超えた場合は終了
if %i% GTR %Acnt% goto :EOF
REM -----------------------------------
REM B配列にデータが存在しない場合の処理
REM -----------------------------------
if "!B[%i%]!"=="" (
REM iが最大値(Acnt)であるか
if %i%==%Acnt% (
REM A[i]がマイナスか
if !A[%i%]! LSS 0 (
REM resultへ0を入力
set /a result[%i%]=0
REM 次の位の処理へ
goto next_number
)
) else (
REM A[i]がマイナスか
if !A[%i%]! LSS 0 (
REM A-Bの結果がマイナス値の場合、10足して計算し直す
set /a result[%i%]=!A[%i%]!+10
REM 次の位をマイナス1処理
goto next_number_down
)
)
REM Aの値をそのままresultへ
set /a result[%i%]=!A[%i%]!
REM 次の位の処理へ
goto next_number
)
REM -----------------------------------
REM A-Bの引き算処理
REM -----------------------------------
REM A-Bの結果をresult[i]へ
set /a result[%i%]=!A[%i%]!-!B[%i%]!
REM 引き算結果が0未満か判定
if !result[%i%]! LSS 0 (
REM A-Bの結果がマイナス値の場合、10足して計算し直す
set /a result[%i%]=!A[%i%]!+10-!B[%i%]!
REM 次の位をマイナス1処理
goto next_number_down
)
:next_number
REM -----------------------------------
REM 通常のカウントアップ
REM -----------------------------------
set /a i=%i%+1
goto subtraction_loop
:next_number_down
REM -----------------------------------
REM カウントアップと次の位をマイナス1
REM -----------------------------------
set /a i=%i%+1
REM 次の位から1引く
set /a A[%i%]=!A[%i%]!-1
goto subtraction_loop
goto :EOF
Adsense
関連記事
-
-
【コマンドプロンプト】バッチファイルでCSVを1行ずつ処理をする方法
僕はプログラマーではないので、あまりカッコイイプログラムはかけませんが、CSVファイルを1行ずつ、バ
-
-
【コマンドプロンプト】バッチでセクション付のINIファイルの読み込み
バッチファイルでINIファイルから値を読み込む 1.INIファイルの用意 以下の「バッチファイル
-
-
【コマンドプロンプト】cmdでSQLの結果を変数に取得する方法
力技の取得方法をご紹介。というかメモ。 題名には偉そうに書きましたが…なかなか良い方法が見つか
-
-
【コマンドプロンプト】前後の不要なスペースの除去(取り除く)
コマンドプロンプトのFOR文とか使って変数に取得しようとすると、取得元のコマンドとかファイルによって
-
-
【コマンドプロンプト】net use で共有フォルダに接続できない場合。
システム エラー 1219 が発生しました。 同じユーザーによる、サーバー
-
-
【コマンドプロンプト】前日日付、月末日付を変数に取得するバッチ。うるう年対応
コマンドプロンプトを使って前日、指定日、月末日付を変数に取得する。 「SearchDay」に入
-
-
【コマンドプロンプト】改行コード CR、LF、CRLFの出力とテキスト書き出し。
仕事でバッチファイルを使っているとログ出力が非常に大事になる。 細かくログを出すことによって、
-
-
【コマンドプロンプト】完成版!cmdでSQLの結果を変数に取得
以前、 【コマンドプロンプト】cmdでSQLの結果を変数に取得する方法 を書きましたが、



