3

出力の一部としての次のスクリプトでは、次のようになります: =-2147483648+312704 Invalid Number. 数値は 32 ビットの精度に制限されています。

これは明らかに符号付き 32 ビット数の範囲内ですが (符号なし 32 のみがサポートされていると考えて 2147483648+312704 も試しました)、同じエラーが発生しました。

奇妙なことに、このスクリプトは WindowsXP では問題なく動作しますが、Windows7 で試してみると、上記のエラーが発生します。

この操作をバッチで実行しないのはなぜですか?

便宜上、コードを以下に示します...

setlocal EnableDelayedExpansion

@set TEMPDIR="%CD%\temp739123834543"
@set ADDR=-2147483648
@set HEXADDR=
@set /a ZIPSLEEP_MS=0

@del frontScreenImages.c
@del frontScreen.zip
@mkdir %TEMPDIR%

for %%f in (*.png) do (

    echo %%~nf
    @call toHex ADDR HEXADDR
    echo "ADDR:!HEXADDR!"
    convertFrontScreenPng.exe %%~nf.png frontScreenImages.c transpose append "0x!HEXADDR!" "__xdata_rom" "#pragma required="
rem    set BINFILE=%TEMPDIR%\a!HEXADDR!_%%~nf.bin
    set BINFILE=%TEMPDIR%\a80000000_frontScreenImages.bin
    echo "BIN:!BINFILE!"
    convertFrontScreenPng.exe %%~nf.png !BINFILE! transpose append
    for %%A in (!BINFILE!) do set /a ADDR=%ADDR%+%%~zA
    set /a ZIPSLEEP_MS=!ZIPSLEEP_MS! + 500
)

@echo Set objArgs = WScript.Arguments > _zipIt.vbs
@echo InputFolder = objArgs(0) >> _zipIt.vbs
@echo ZipFile = objArgs(1) >> _zipIt.vbs
@echo CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar) >> _zipIt.vbs
@echo Set objShell = CreateObject("Shell.Application") >> _zipIt.vbs
@echo Set source = objShell.NameSpace(InputFolder).Items >> _zipIt.vbs
@echo objShell.NameSpace(ZipFile).CopyHere(source) >> _zipIt.vbs
@echo wScript.Sleep !ZIPSLEEP_MS! >> _zipIt.vbs

@CScript  _zipIt.vbs  %TEMPDIR%  "%CD%\frontScreen.zip"

@del   _zipIt.vbs
@rmdir %TEMPDIR% /s /q
sleep 3
4

1 に答える 1

2

David RuhmannEndoroの回答を追加情報とともに繰り返します。

CMD.EXE が数値を解析する方法のルールで-2147483648、Windows XP では問題がなくても、Windows Vista、Windows 7、およびおそらく Windows 8 で数値を解析すると値が無効な数値エラー メッセージになる理由について説明されています。string から signed/unsigned int への変換のコードは、 のソース コードでは不十分に記述されcmd.exeているため、最小の符号付き 32 ビット整数に対して正しく機能しません。

このバッチ ファイルの 1 つの解決策は、

set /a ADDR+=%%~zA

それ以外の

set /a ADDR=%ADDR%+%%~zA

これにより、コマンドラインが表示されます

set /a ADDR+=312704

それ以外の

set /a ADDR=-2147483648+312704

しかし、それだけが唯一の解決策ではありません

@echo off
set VALUE1=-2147483648
set VALUE2=312704
set /a RESULT=%VALUE1%+%VALUE2%
echo Result of %VALUE1% + %VALUE2% is %RESULT%

Windows 7 および Vista で実行すると、エラー メッセージが表示されます。

もう 1 つの解決策は、コード化が不十分なプリプロセッサで同じ問題を回避するためlimits.hに、C/C++ のほとんどがINT_MINプリプロセッサ マクロに含むものです: 最小符号付き 32 ビット整数を固定値ではなく式として定義することです。

#define INT_MIN  (-2147483647-1)
#define LONG_MIN (-2147483647L-1L)

この回避策は、上記の小さなバッチ ファイルに適用されます。

@echo off
set VALUE1=(-2147483647-1)
set VALUE2=312704
set /a RESULT=%VALUE1%+%VALUE2%
echo Result of %VALUE1% + %VALUE2% is %RESULT%

これで、Windows 7 および Vista でもバッチ ファイルの実行に問題がなくなりました。

于 2014-07-05T13:25:26.507 に答える