Pirm
Pirm

Reputation: 35

How to divide possibly big numbers in Batch?

My question concerns a script I'm writing to automatically back up several Folders and subfolders with a batch file.
Now I'm trying to implement some kind of progress indicator in a readable format, preferably in per cent.
First of all, it reads the total size to copy with the following command:

FOR /R "C:\Users\XXX" %%F IN (*.*) DO (
set /a overall=!overall!+%%~zF
)

For the specific folder in my testing batch, this returns a size of 266,173,879 Bytes.
However, if I try to divide this number by, say, 1024 (for Kilobytes) after the for-loop with

set /a overall=%overall%/1024

the Batch returns something along the lines of "/1024 can not be used here syntactically" (You probably know the correct translation, mine is in German).
I tried adding/removing parantheses and spaces, but I keep getting the same error.

Is there something wrong with my syntax, which I'm too blindfolded to see?
If not, how do you call a C++ .exe delivering the value of %overall% to be assigned to a C++ variable? (C++ is the only other programming language I have minimal to basic knowledge of, PowerShell is not an option, it has to be regular Windows Batch)

complete code of relevance:

FOR /R "C:\Users\XXX" %%F IN (*.*) DO (
set /a overall=!overall!+%%~zF
)

set /a overall=%overall%/1024

FOR /R "C:\Users\XXX" %%F IN (*.*) DO (
xcopy "%%F" "E:%%~pF" %parameter%>nul
cls
echo Copying... Progress: !size! of !overall! KB copied.
)

Upvotes: 3

Views: 6270

Answers (3)

GolezTrol
GolezTrol

Reputation: 116140

The error suggests that the expression has a syntax error. The number you are trying to device is 260 million, which is safely within the maximum precision of 32 bits numbers that batch can handle.

I think the problem is that the value is actually 266,173,879, including the commas. Depending on your localisation settings, the division may fail over those characters.

If I try 266,173,879/1024, it always returns 0, which is not good. If I try 266.173.879/1024, it says 'missing operator', which in't right either.

Another possibility is that %overall% hasn't got a value the first time. That makes the expression look like

set /a overall=/1024

That is, of course, invalid and returns the error missing operand, which is slightly different from missing operator mentioned above.

If think the safest thing is to make sure that %overall% has a value first, and try to remove the commas from the string next.

After that it should work:

C:\>set /a overall=266173879/1024
259935

Note that you will get in trouble when your directory is larger than 2 GB.

Upvotes: 0

David Ruhmann
David Ruhmann

Reputation: 11367

Here is some good info about Batch files and their math limitations. The page also has some information on how to best deal with these limitations.

There is a severe limitation in batch math: it can only handle 32-bit integers. http://www.robvanderwoude.com/battech_math.php

Which is 4,294,967,295 for unsigned, −2,147,483,648 to 2,147,483,647 for signed.


For simplicity, you may just want to look into using robocopy if you are using Windows 2003/XP or newer. Note that you must install the Windows Resource Pack (Works on XP) to add the robocopy tool. See the robocopy link for all the features and logging options.

Upvotes: 2

Bali C
Bali C

Reputation: 31241

I don't know how batch handles numbers, but I think using C++ would be a better choice, as you can use an int, long etc, for whatever number you need.

You can pass your numbers to your C++ app using

yourcpp.exe !overall! 1024

and pick them up using main's arguments and divide them (my C++ isn't great, but something like this should do)

int main(int argc, char* argv[]) {
double n = (double)argv[0]/(double)argv[1];
return 0;
}

Then you can store it how you want, maybe output to a text file, which you can read using the batch file.

Upvotes: 0

Related Questions