Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Неверное число. Числа ограничены 32 битами точности. (http://forum.oszone.net/showthread.php?t=234593)

sLiDeR-X 14-05-2012 07:27 1915497

Неверное число. Числа ограничены 32 битами точности.
 
Вложений: 1
Даю батнику команду:
Код:

set /a TotalSelectSize=%HomeMB%+%WinXPMB%+%Win7MB%+%LiveCDMB%+%HirenMB%+%RecoverMB%+%DriverMB%+%WPIMB%+%SoftMB%
А он мне в ответ:
Код:

set /a TotalSelectSize=24006839+597176320+4032823296+601608192+493252608+1663288361+4679008256+2420684800+29275962
Неверное число. Числа ограничены 32 битами точности.

Как правильно посчитать сумму?

Пробовал делать так:
Код:

set /a WinXPMB=%WinXPMB%/1000000
и т.д. Тогда ошибки не появляется, но зато некоторые значения получаются корректные, т.е. 24006839 --> 24, а некоторые нет, например, 4032823296 --> -262
Код:

set /a TotalSelectSize=24+597+-262+601+493+1663+4679008256+-1874+29
Не пойму никак почему такое происходит.

Iska 14-05-2012 07:40 1915500

Цитата:

Цитата sLiDeR-X
Как правильно посчитать сумму? »

Правильно — переходить на WSH, а ещё лучше — сразу на PowerShell.

sLiDeR-X 14-05-2012 07:44 1915501

У меня задача посчитать размер определенных папок + файлов и вывести значения посчитанных папок и файлов в переменные для дальнейшей работы.

Petya V4sechkin 14-05-2012 08:08 1915509

Расширение 32-битной арифметики

Iska 14-05-2012 08:23 1915512

sLiDeR-X, ну, выведете Вы эти значения в переменные. А дальше-то что? Не думаете ли Вы, что проблема только в «set /a», и стоит её как-нибудь решить, то «дальше мы уж как-нибудь разберёмся»?! Вот Вам простой пример:
Код:

@echo off
setlocal enableextensions enabledelayedexpansion

set TotalSelectSize=3000000000
set sTerminateSize=20000000000

if %TotalSelectSize% lss %sTerminateSize% (
        echo %TotalSelectSize%
        echo меньше чем
        echo %sTerminateSize%
) else (
        echo %TotalSelectSize%
        echo больше чем
        echo %sTerminateSize%
)

endlocal
exit /b 0

Цитата:

Код:

3000000000
больше чем
20000000000



sLiDeR-X 14-05-2012 09:04 1915520

Iska, это все понятно...
Для себя в этом же скрипте делаю так:
Код:

set "TotalSelectSize_=000000000000000000%TotalSelectSize%"& set "TotalSelectSize_=!TotalSelectSize_:~-18!"
set "$FreeDiskSize_=000000000000000000%$FreeDiskSize%"& set "$FreeDiskSize_=!$FreeDiskSize_:~-18!"
if "%TotalSelectSize_%" LEQ "%$FreeDiskSize_%" (call :BigDisk) else (call :SmallDisk)

Но такой метод неудобно использовать при большом количестве слагаемых.

Вывернулся вот таким способом:
Код:

for /f "skip=4 tokens=1-3" %%a IN ('dir "___Main\" /-C /S /A:-D') do (
        if !flag!==1 set HomeMB=%%c
        if "%%b"=="файлов:" (set flag=1) else (set flag=0)
)
set /a HomeMB=%HomeMB%/1000000
echo HomeMB %HomeMB%

for %%i in (%RDS_Sourse%\WindowsXP\*.iso) do set WinXPMB=%%~zi
set WinXPMB=%WinXPMB:~0,-6%
echo WinXPMB %WinXPMB%

и т.д.

set /a TotalSelectSize=%HomeMB%+%WinXPMB%+%Win7MB%+%LiveCDMB%+%HirenMB%+%RecoverMB%+%DriverMB%+%WPIMB%+%SoftMB%
echo TotalSelectSize %TotalSelectSize%

и в итоге:
Код:

set /a TotalSelectSize=24+597+4032+601+493+1663+4679+2420+29
echo TotalSelectSize 14538

что и хотел :)

CyberMuesli 20-05-2012 13:47 1919214

Набросал вот. Можно оперировать очень большими числами, а также дробными. В коде функция и наглядный пример использования

ps. Вообще, конечно, BAT это ЖЕСТЬ и писать на нем могут только упоротые маньяки. Типичная проблема - поиск неправильной закорючки и попытка понять, как надо расставить закорючки, чтобы оно не ругалось. Результат выполнения if %PercentFree% LSS %MinPercentFree% если числа содержат запятую меня просто убил - выполняются обе ветки IF, пришлось менять на if %PercentFree:,=% LSS %MinPercentFree:,=% (

Код:

@echo off

setlocal enabledelayedexpansion

set BatMaximum=0xFFFFFFFF
set /a BatMaximum=BatMaximum+0

echo Calculating: %BatMaximum% + 2
set /a InvalidResult=BatMaximum+2
echo Invalid result: %InvalidResult%
call :Calculate "%BatMaximum% + 2"
echo Right result: "%CalcResult%"

echo ---- more samples: ----

set TotalDiskSize=512*1024*1024*1024
set FreeSpace=32*1024*1024*1024
set MinPercentFree=0,100

call :Calculate %TotalDiskSize%
set TotalDiskSize=%CalcResult%

call :Calculate -delim %TotalDiskSize% 15
echo Disk size : %CalcResult% bytes

call :Calculate %FreeSpace%
set FreeSpace=%CalcResult%

call :Calculate -delim %FreeSpace% 15
echo Free space: %CalcResult% bytes

call :Calculate "(%FreeSpace%)/(%TotalDiskSize%)" 5 3
set PercentFree=%CalcResult%

if %PercentFree:,=% LSS %MinPercentFree:,=% (
  echo Too low free disk space: %PercentFree%%%, must be minimum: %MinPercentFree%%%
) else (
  echo Free space is enough: %PercentFree%%%
)
exit

::===========
:Calculate
::===========
:: Params: [-debug] [-delim] %1=Formula [%2=Len [%3=Dec] ]
:: Return: %CalcResult%
set Calculate.StdOut=StdOut%Random%.tmp
set Calculate.Vbs=Calc%Random%.vbs
set Calculate.UseDelim=False
set Calculate.Debug=False

:Calculate.ParseParam

rem echo %1 %2 %3 %4 %5 loop Calculate.Debug=%Calculate.Debug%

if /i "%~1"=="-debug" (
  shift
  set Calculate.Debug=True
  goto Calculate.ParseParam
)
if /i "%~1"=="-delim" (
  shift
  set Calculate.UseDelim=True
  goto Calculate.ParseParam
)

if %Calculate.Debug%==True (
  echo Formula: "%~1"
)

>%Calculate.Vbs% (
echo Set FSO = CreateObject^("Scripting.FileSystemObject"^)
echo Set TF = FSO.CreateTextFile^("%Calculate.StdOut%",True^)
echo on error resume next
)
echo Result=%~1 >>%Calculate.Vbs%
if not "%2"=="" (
  if not "%3"=="" (
      echo Result = FormatNumber^(Result, %3,,, %Calculate.UseDelim% ^) >>%Calculate.Vbs%
  ) else (
      echo Result = FormatNumber^(Result,  0,,, %Calculate.UseDelim% ^) >>%Calculate.Vbs%
  )
  >>%Calculate.Vbs% (
      echo If Len^(Result^) ^< %2 Then
      echo    Result = String ^( %2 - Len^(Result^), chr^(32^) ^) + Result
      echo End If
  )
)
>>%Calculate.Vbs% (
echo TF.Write Result
echo TF.Close
)
%Calculate.Vbs%
for /f "delims=■" %%i in (%Calculate.StdOut%) do (
    set CalcResult=%%i
)

del %Calculate.StdOut% >nul 2>&1
del %Calculate.Vbs% >nul 2>&1
:goto eof



Время: 17:11.

Время: 17:11.
© OSzone.net 2001-