【コマンドプロンプト】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
関連記事
-
【コマンドプロンプト】前後の不要なスペースの除去(取り除く)
コマンドプロンプトのFOR文とか使って変数に取得しようとすると、取得元のコマンドとかファイルによって
-
【コマンドプロンプト】バッチでセクション付のINIファイルの読み込み
バッチファイルでINIファイルから値を読み込む 1.INIファイルの用意 以下の「バッチファイル
-
【コマンドプロンプト】完成版!cmdでSQLの結果を変数に取得
以前、 【コマンドプロンプト】cmdでSQLの結果を変数に取得する方法 を書きましたが、
-
【コマンドプロンプト】前日日付、月末日付を変数に取得するバッチ。うるう年対応
コマンドプロンプトを使って前日、指定日、月末日付を変数に取得する。 「SearchDay」に入
-
【コマンドプロンプト】cmdでSQLの結果を変数に取得する方法
力技の取得方法をご紹介。というかメモ。 題名には偉そうに書きましたが…なかなか良い方法が見つか
-
【コマンドプロンプト】バッチファイルでCSVを1行ずつ処理をする方法
僕はプログラマーではないので、あまりカッコイイプログラムはかけませんが、CSVファイルを1行ずつ、バ
-
【コマンドプロンプト】net use で共有フォルダに接続できない場合。
システム エラー 1219 が発生しました。 同じユーザーによる、サーバー
-
【コマンドプロンプト】改行コード CR、LF、CRLFの出力とテキスト書き出し。
仕事でバッチファイルを使っているとログ出力が非常に大事になる。 細かくログを出すことによって、