I have a script that calculates disk space in bytes. I have found a way to convert it to megabytes. I have just run it and i got a this: 1867.603187561035
. Is there
It would be better if you showed the script in question, but yes, rounding can be performed. We just have to do the process manually. Here is a routine that will take in the number and a variable for the result.
:Round <Input> <Output>
setlocal
for /f "tokens=1,2 delims=." %%A in ("%~1") do set "X=%%~A" & set "Y=%%~B0"
if %Y:~0,1% geq 5 set /a "X+=1"
endlocal & set "%~2=%X%"
exit /b 0
Usage:
@echo off
setlocal
call :Round 12345.6789 Out
echo %Out%
endlocal
exit /b 0
@echo off
set "number_to_round=1867.603187561035"
for /f "tokens=1,2 delims=." %%a in ("%number_to_round%") do (
set first_part=%%a
set second_part=%%b
)
set second_part=%second_part:~0,1%
echo %second_part%
if defined second_part if %second_part% GEQ 5 (
set /a rounded=%first_part%+1
) else (
set /a rounded=%first_part%
)
echo %rounded%
OR (with the javascript call you can get more precise results and work with long number (while batch is limited to integers))
@echo off
set number_to_round=1867.603187561035
set "beginJS=mshta "javascript:close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(Math.round(%number_to_round%)"
set "endJS=));""
for /f %%N in (
'%beginJS%%endJS%'
) do set rounded=%%N
echo %rounded%
Here is a native batch/jscript hybrid posted recently that will
return a MB
figure, for a byte
figure given as %1
(and not limited to 2GB figures as batch math is)
It does not round up or round down the partial megabyte after the decimal point, it just removes it.
@if (@CodeSection == @Batch) @then
@echo off
set JScall=Cscript //nologo //E:JScript "%~F0"
for /f "delims=." %%a in ('%JScall% "%~1/1024/1024"') do set "size=%%a"
echo %size%
goto :EOF
@end
WScript.Echo(eval(WScript.Arguments.Unnamed.Item(0)));
There is an even easier way to round a number to the nearest integer, supposing it is not negative and less than 100000000
:
set NUMBER=1867.603187561035
rem // Enforce fractional part:
set NUMBER=%NUMBER%.
rem // Get integer part:
set /A NROUND=NUMBER+0
rem // Extract fractional part:
set NFRACT=%NUMBER:*.=%0
rem /* Prepend `1` to integer part to avoid trouble with leading `0`
rem (remember that such numbers are interpreted as octal ones);
rem append first fractional digit to integer part, then add `5`: */
set /A NROUND=1%NROUND%%NFRACT:~,1%+5
rem // Strip off first and last digits and return remaining integer:
if %NROUND:~,1% GTR 1 (echo 1%NROUND:~1,-1%) else (echo %NROUND:~1,-1%)
To round a signed number in the range between −100000000
and +100000000
to the nearest integer, use this code snippet:
set NUMBER=1867.603187561035
rem // Enforce fractional part:
set NUMBER=%NUMBER%.
rem // Get integer part:
set /A NROUND=NUMBER+0
rem // Cache sign and remove it temporarily:
if %NROUND% LSS 0 (set /A NROUND=-NROUND & set SIGN=-) else set SIGN=
rem // Extract fractional part:
set NFRACT=%NUMBER:*.=%0
rem /* Prepend `1` to integer part to avoid trouble with leading `0`
rem (remember that such numbers are interpreted as octal ones);
rem append first fractional digit to integer part, then add `5`: */
set /A NROUND=1%NROUND%%NFRACT:~,1%+5
rem // Strip off first and last digits and return remaining integer:
if %NROUND:~,1% GTR 1 (echo %SIGN%1%NROUND:~1,-1%) else (echo %SIGN%%NROUND:~1,-1%)
The above approaches may have problems with numbers with leading zeros (due to the fact that such are interpreted as octal numbers), and the used method of temporarily preceding and appending digits reduces the available numerical range.
However, here is now a script that does not have these restrictions:
findstr
) to check the number format;.5
is only rounded up when the integer part is odd (so 1.5
becomes 2
, and 2.5
becomes 2
too);.5
) by removing the condition if "%NFRACT:~,1%"=="5"
and just keeping the code in the else
clause;So this is the code:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Provide a (signed) fractional number here:
set "NUMBER=%~2"
if defined NUMBER exit /B 1
set "NUMBER=%~1"
if not defined NUMBER set /P NUMBER=""
rem // Check whether or not the provided fractional number is actually such:
cmd /V /C echo(!NUMBER!| > nul findstr /R ^
/C:"^ *[+-][0123456789]* *$" /C:"^ *[+-][0123456789]*\.[0123456789]* *$" ^
/C:"^ *[0123456789]* *$" /C:"^ *[0123456789]*\.[0123456789]* *$" || exit /B
rem // Remove quotation marks, remove leading white-spaces, append dot:
if defined NUMBER set "NUMBER=%NUMBER:"=%
for /F "tokens=* eol= " %%S in (" %NUMBER%.") do set "NUMBER=%%S"
rem // Determine sign:
set "SIGN=" & if "%NUMBER:~,1%"=="-" (
set "NUMBER=%NUMBER:~1%" & set "SIGN=-"
) else if "%NUMBER:~,1%"=="+" (
set "NUMBER=%NUMBER:~1%" & rem set "SIGN=+"
)
rem // Remove leading zeros to avoid interpretation as octal number:
for /F "tokens=* eol=0 delims=0" %%Z in ("%NUMBER%") do set "NUMBER=%%Z"
rem // Split number into integer and fractional parts:
for /F "tokens=1 eol=. delims=." %%I in ("1%NUMBER%") do set "NROUND=%%I"
set "NROUND=%NROUND:~1%" & set "NFRACT=%NUMBER:*.=%0"
for /F "delims=0123456789 eol=0" %%J in ("%NROUND:~1%") do set "NFRACT=0"
rem // Actually round:
if "%NFRACT:~,1%"=="5" (
rem /* Particularly handle the exact fractional portion `.5` in order
rem to round mathematically correct, thus to the nearest even: */
for /F "tokens=* eol=0 delims=0" %%T in ("0%NFRACT:~1%") do (
set "NFRACT=%%T" & set /A "NROUND+=!!(NFRACT+NROUND%%2)"
)
) else (
set "NFRACT=%NFRACT:~,1%" & set /A "NROUND+=NFRACT/5"
)
rem // Correct wrong sign when (2^31 - 1) needed to be rounded up:
if %NROUND% lss 0 set /A "NROUND-=1"
rem // Return resulting rounded number:
if %NROUND% equ 0 (echo %NROUND%) else echo %SIGN%%NROUND%
endlocal
exit /B
If you just want get the number before the .
:
@echo off
set $value=1867.703187561035
for /f "tokens=1 delims=." %%a in ('echo %$Value%') do set %$number%=%%a
echo %$Number%
And if you really want to test the second part of the number :
@echo off
setlocal EnableDelayedExpansion
set $value=1867.703187561035
for /f "tokens=1,2 delims=." %%a in ('echo %$Value%') do (
set $Number=%%a
set $Vtest=%%b
if "!$Vtest:~0,1!" geq "5" set /a $Number+=1
)
echo !$Number!