如果IF比較的兩邊都嚴格由十進制數字組成,那麼IF將把兩邊解釋爲數字。這使得IF能夠正確地確定10大於9.如果你有任何非數字字符,那麼IF做字符串比較。例如,「10」小於「9」,因爲引號不是數字,低於9則爲1。
問題比較失敗的原因是因爲CMD.EXE無法處理大於2147483647的數字。 IF中奇怪的設計怪癖將大於2147483647的任何數字視爲等於2147483647.
如果要對大數字進行字符串比較,那麼解決方案很簡單。您只需要在條件的兩側添加一個或多個非數字字符。下面的腳本 -
@echo off
setlocal
set n1=30000000000000
set n2=40000000000
if "%n1%" gtr "%n2%" echo "%n1%" is greater than "%n2%"
if "%n1%" lss "%n2%" echo "%n1%" is less than "%n2%"
if "%n1%" equ "%n2%" echo "%n1%" is equal to "%n2%"
產生正確的字符串比較結果
"30000000000000" is less than "40000000000"
但在大多數情況下,這不是什麼都想。
如果你想做一個數字比較,那麼這個過程會涉及更多一點。您需要將該號碼轉換爲一個字符串,該號碼可以正確排序爲一個數字。這是通過在數字字符串前加上零來實現的,它使兩個數字字符串具有相同的寬度。最簡單的解決方案是確定您需要支持的最大位數 - 例如,15。因此,您用15個零來爲每個值加前綴,然後通過使用子字符串操作僅保留最右邊的15個字符。您還需要像以前一樣向雙方添加非數字 - 再次引用工作良好。
這個腳本 -
@echo off
setlocal
set n1=30000000000000
set n2=40000000000
call :padNum n1
call :padNum n2
if "%n1%" gtr "%n2%" echo %n1% is greater than %n2%
if "%n1%" lss "%n2%" echo %n1% is less than %n2%
if "%n1%" equ "%n2%" echo %n1% is equal to %n2%
exit /b
:padNum
setlocal enableDelayedExpansion
set "n=000000000000000!%~1!"
set "n=!n:~-15!"
endlocal & set "%~1=%n%"
exit /b
生產 -
030000000000000 is greater than 000040000000000
注意,留下了空間前綴效果一樣好爲零。
,只要你想使用以下以後,您可以刪除前導零(或適應刪除前導空格)
for /f "tokens=* delims=0" %%A in ("%n1%") do set "n1=%%A"
if not defined n1 set "n1=0"
通常我們不處理在批處理文件中大量涌現。但是如果我們查看硬盤上的可用空間,他們很容易出現問題。太字節磁盤驅動器現在相對便宜。這是我第一次碰到大數的比較https://stackoverflow.com/a/9099542/1012053
我選擇在我的例子中支持15位數,因爲這相當於幾乎999千兆字節。我想這將是一段時間,然後才能處理比這更大的磁盤驅動器。 (但誰知道!)
編輯 - 我對IF如何解析數字的描述是故意過於簡單化的。 IF實際上支持負數,以及十六進制和八進制符號。有關更詳盡的解釋,請參閱Rules for how CMD.EXE parses numbers。
這真的很棒。謝謝 – Lupocci 2016-10-26 12:11:52
如果雙方都是格式良好的數字 - 不僅僅是嚴格的十進制數字,數字比較就完成了。例如-1或0xabc或+43會比較數字,但09不會(09是無效的八進制)。 – 2017-05-24 06:22:51
@PaulH - 絕對正確,但我不想分散處理大量問題的問題的中心點。我努力想出一個簡潔的解釋,它不會壓倒大數字被視爲最大允許整數的觀點。更多信息可以在[CMD.EXE如何解析數字的規則]中找到(http://www.dostips.com/forum/viewtopic.php?t=3758) – dbenham 2017-05-24 13:12:36