Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid number. Numbers are limited to 32-bits of precision

Found this script on the net. It works for the basic reason I downloaded it. But I would like to know a couple things:

  1. When the script attempt to divide the bytes to KB, MG and GB it errors with Invalid number. Numbers are limited to 32-bits of precision.
  2. Total Number for Files & Directories are missing the close parenthesis.

CODE:

c:
cd\
@Echo ------------------------------------------------------
@Echo ------------------------------------------------------
@For /F "tokens=*" %%a IN ('"hostname"') do @Set summaryouthost=%%a
@Echo Integrity Check on: %summaryouthost%

@For /F "tokens=*" %%a IN ('"chdir"') do @Set summaryoutchdir=%%a
@Echo Integrity Check For the path: %summaryoutchdir%
@Echo ------------------------------------------------------

@For /F "tokens=*" %%a IN ('"date /T"') do @Set summaryoutsdate=%%a
@Echo Start Date: %summaryoutsdate%

@For /F "tokens=*" %%a IN ('"time /T"') do @Set summaryoutstime=%%a
@Echo Start time: %summaryoutstime%

@Echo ------------------------------------------------------
@For /F "tokens=*" %%a IN ('"dir /s /-c | find "bytes" | find /v "free""')  do @Set summaryout=%%a
::@Echo %summaryout%
@For /f "tokens=1,2 delims=)" %%a in ("%summaryout%") do @set filesout=%%a&set sizeout=%%b
@For /f "tokens=*" %%a IN ('"dir /s /-c | find "bytes free""') do @Set summaryoutdir=%%a
::@Echo %summaryoutdir%
@For /f "tokens=1,2 delims=)" %%a in ("%summaryoutdir%") do @set filesoutdir=%%a&set sizeoutdir=%%b
@Set sizeout=%sizeout:bytes=%
::@Echo %sizeout%

@Set sizeout=%sizeout: =%
@set /A inbytes=%sizeout%
@set /A inkb=(%sizeout%) / 1024
@set /A inmb=(%sizeout%) / (1024*1024)
@set /A ingb=(%sizeout%) / (1024*1024*1024)

@For /F "tokens=*" %%a IN ('"date /T"') do @Set summaryoutedate=%%a
@Echo End Date: %summaryoutedate%

@For /F "tokens=*" %%a IN ('"time /T"') do @Set summaryoutetime=%%a
@Echo End time: %summaryoutetime%

@Echo ------------------------------------------------------
@Echo Total Number of Files is:%filesout%
@Echo Total Number of Directory is: %filesoutdir%
@Set sizeoutdir=%sizeoutdir:bytes=%
::@Echo %sizeoutdir%
@Set sizeoutdir=%sizeoutdir: =%
@Echo ------------------------------------------------------
@Echo Total Size is (BY) :%sizeout%
@Echo Total Size is (KB) :%inkb%
@Echo Total Size is (MB) :%inmb%
@Echo Total Size is (GB) :%ingb%
@Echo ------------------------------------------------------
@Echo Free Space is :%sizeoutdir%
@Echo ------------------------------------------------------
@Echo ------------------------------------------------------

OUTPUT:

------------------------------------------------------ 
------------------------------------------------------ 
Integrity Check on: Laptop01 
Integrity Check For the path: C:\ 
------------------------------------------------------ 
Start Date: Sun 10/04/2015  
Start time: 12:34 AM
------------------------------------------------------
Invalid number. Numbers are limited to 32-bits of presision.
Invalid number. Numbers are limited to 32-bits of presision.
Invalid number. Numbers are limited to 32-bits of presision.
Invalid number. Numbers are limited to 32-bits of presision.
End Date: Sun 10/04/2015   
End time: 12:36 AM  
------------------------------------------------------ 
Total Number of Files is:333914 File(s 
Total Number of Directory is: 185869 Dir(s 
------------------------------------------------------ 
Total Size is (BY) :248159912076  
Total Size is (KB) : 
Total Size is (MB) : 
Total Size is (GB) : 
------------------------------------------------------ 
Free Space is :625324642304free  
------------------------------------------------------ 
------------------------------------------------------ 

Thanks in advance for any help.

like image 487
Tom1029 Avatar asked Mar 15 '23 14:03

Tom1029


2 Answers

Numbers are limited to 32-bits of precision.

This is a limitation of set /a.

For workarounds see "Workarounds: 32-bit" below.

Arithmetic expressions (SET /a)

...

The numbers must all be within the range of 32 bit signed integer numbers (-2,147,483,648 through 2,147,483,647) to handle larger numbers use PowerShell or VBScript.

Source set


Workarounds: 32-bit

Workarounds for the 32-bit limitation include:

  1. dividing by 1000 (or any power of 10) by chopping off the last (3) digits
  2. splitting up the numbers into separate decimal digits and perform all the math and carry logic "manually"
  3. other scripting languages

Workaround #1 can be used to add up disk space:

  • "Chop" code example

The trick is that each (big) number is treated as strings, then the rightmost 6 characters (digits) are chopped off, and only then the result is treated as a number.

This is a rather crude workaround, as it "rounds" all numbers before doing the math.

Adding half a MegaByte for each subdirectory (%Count% / 2) to %Total% does compensate for the truncations, though, so the grand total is more accurate than the individual numbers.

Note that the numbers don't represent "real" MegaBytes (1024 x 1024) buth rather Million Bytes (1000 x 1000).

Workaround #2 is perfectly demonstrated by Brian Williams' batch files:

  • Add.bat
  • IsLarger.cmd
  • Multiply.cmd

Workaround #3, other scripting languages, is self-explanatory.

Source Math in NT batch files


Further Reading

  • An A-Z Index of the Windows CMD command line - An excellent reference for all things Windows cmd line related.

  • set - Display, set, or remove CMD environment variables. Changes made with SET will remain only for the duration of the current CMD session.

like image 187
DavidPostill Avatar answered Apr 26 '23 17:04

DavidPostill


If you need an easy cheat for diskspace, you can do a cruder calculation by subsetting the string and dividing by an approximation. Like so:

@set /A ingb=%sizeout:~0,-7% / (1074)

Where %sizeout:~0,-7% substrings sizeout, which is a crude way of dividing by 1.000.000 without handling any issues of rounding, and where 1074 is calculated 1024*1024*1024 / 1.000.000

The same would be done for all the size you need (KB and MB).

MB: %sizeout:~0,-4% / 1049

KB: %sizeout:~0,-4%

Of course the numbers would be increasingly inaccurate the lower the measurement-units, but for GB it was plenty accurate for me to use it to monitor disk space on machines.

I realise that all of this can also be deducted from DavidPostill's answer, but I just wanted to bring a copy paste example that applies to this specific situation.

like image 37
Ashes Avatar answered Apr 26 '23 17:04

Ashes