If greater than in batch files [duplicate] - batch-file

This question already has an answer here:
Windows batch file IF failure - How can 30000000000000 equal 40000000000?
(1 answer)
Closed 5 years ago.
I have a very silly issue but unable to figure out what is wrong
I'm doing a basic level number comparison in if statement. script is pasted below. geq-greater than or equal to is working fine but gtr-greater than has a problem. Is there any limitation for numbers in gtr comparison?
if 3 gtr 2 (#echo "greater") else (#echo "lesser")
greater
if 3 geq 2 (#echo "greater") else (#echo "lesser")
greater
if 135149772801 gtr 111110000000 (#echo "greater") else (#echo "lesser")
lesser
if 135149772801 geq 111110000000 (#echo "greater") else (#echo "lesser")
greater

Is there any limitation for numbers in gtr comparison?
Yes, there really is.
You're limited to 32-bit signed integers and, if there's overflow, it's set to the maximum value.
Since both those numbers, 135149772801 and 111110000000, are too big, they're both converted to 231 - 1.
That's why it says the first is not greater (which is subtly different to lesser, by the way) but it is greater than or equal to.
More details can be found at the excellent dostips site.

A way around the 32-bit limit is to prefix the numeric-string with a goodly number of 0 and then use an alphabetic comparison on the last n characters.
Hence
set "num1=135149772801"
set "num2=111110000000"
set "zeroes=00000000000000000000000000000000000000000000000000000"
set "comp1=%zeroes%%num1%"
set "comp2=%zeroes%%num2%"
if "%comp1:~-20%" gtr "%comp2:~-20%" (echo greater) else (echo not greater)
where "-20" above means "take the last 20 characters"

A batch-file natively supports 32-bit signed integer arithmetic only. If the number goes over 2147483648, it overflows and warp back to negative number. However in if statements, the number gets clutter back to 2^31-1.
Code | Code Result | Actual Result
-----------------------+-------------------+-----------------------
2147483647 + 1 2147483648 2147483648
2147483648 + 1 -2147483648 2147483649
Here is some possible workaround:
Chopping the number(making the number smaller before comparing)
Other scripting languages(use powershell or vbs to compare)
Embedded Powershell solution:
for /f %p in ('powershell -command if (1 -gt 0^) {write-host greater} else {write-host lesser}') do echo %p
This command calls powershell to compare, and retrieve the results using a for loop.

Related

Simple IF statement with more than 1 digit numbers?

Below I'm testing a simple IF statement but it doesn't seem to take the whole number I'm comparing in to account. You can see this number is greater than "2", but with my result it's like it's only reading the "1" and that's it, so telling me the number is "Less or Equal" than "2", I would expect the result "LARGE" to be returned. How can I get it to read the whole number and not just the first digit?
IF "1073740972" LEQ "2" (
ECHO LESS or EQU 2
) ELSE (
ECHO LARGE
)
The "LARGE" number is an %ERRORLEVEL% generated number so this can be different each time.
I have tried Changing [LEQ "2"] to [LSS "3"] but I do not know what else I could try.
Thanks in advance
Remove the quotation marks from the comparison expressions:
IF 1073740972 LEQ 2 (
ECHO LESS or EQU 2
) ELSE (
ECHO LARGE
)
Otherwise, no numeric but string comparison is performed, where the character codes are regarded, so character 1 (ASCII 49 = 0x31) is less than character 2 (ASCII 50= 0x32).

Why can't I use -2147483648 in an expression of `set /A` directly?

As you might have noticed, -2147483648 = -231 is the negative limit of the signed 32-bit integer range.
When I try to use this value literally...:
set /A -2147483648
..., the following error occurs:
Invalid number. Numbers are limited to 32-bits of precision.
However, I can state the positive limit 2147483647 = 231 - 1 without any trouble:
set /A 2147483647
So why does set /A behave like that, although the number is perfectly within the applicable range for signed two's complement 32-bit integers?
And is there a way to state the constant -2147483648 directly in a set /A expression?
I know, I could use a variable that is preset to the value, like set NEGLIM=-2147483648, and then use it in an unexpanded way, like set /A NEGLIM, but is there not an immediate way of providing that value?
I propose the following workaround:
set /A -2147483647-1
result:
-2147483648
funny note: set /A -2147483647-2 yields 2147483647 so toying with the limit is dangerous :)
I just found an interesting fact: when using hexadecimal representation, the negative limit can be given:
set /A -0x80000000
Or (also resulting in -2147483648 due to the two's complement representation):
set /A +0x80000000
However, octal notation fails just like the decimal one:
rem These fail:
set /A -020000000000
set /A +020000000000

Batch - Multiple commands if button press

I'm coding a simple game and needed help,
pcash = user cash
reshp1 = cost to restore hp
php = player health
How do I write these into 1 line?
If user press 1, check if cash is equal or greater to the cost of restore hp, if it is greater - subtract cash base on cost of restore hp, then finally add the hp by 20%.
This is what I have tried, but did not work as expected.
if "%restorer%"=="1" if %pcash% geq %reshp1c% && set /a pcash=%pcash% - %reshp1c% && set /a php=%php% * .20
if "%restorer%"=="1" if %pcash% geq %reshp1c% set /a pcash=%pcash% - %reshp1c%&set /a php=%php%*6/5
& is used to separate cascaded statement. Batch uses integer mathematics, so *6/5 will multiply by 6 then divide by 5, adding 20% to the prior value (your code, had it worked, would have set the value to 20% of its prior magnitude)

Check if there's a difference between two variables

I have two variables. var1 = 1.0 ; var2 = 0.9.
I want to do this:
set var1=1.0
set var2=0.9
if %var1%=%var2% echo equal
if %var1%(not equal to)%var2% echo not equal
pause
Does anybody know what look the "not equal" symbol should look like?
if "%var1%" neq "%var2%"
or
if not "%var1%"=="%var2%"
Type help if in a console window for more info. You should also get into the habit of enclosing both sides of the == signs in quotation marks, in case one of the variables contains a space.
if %var1% neq %var2% echo not equal
there's also geq gtr lss leq and equ (greater or equal, greater, less, less or equal and equal)
But - it's best to use "quotedvariablenames" on both sides of the comparison if you're using strings that contain separators (like spaces) and you can also use
if /i ...
to compare the strings case-insensitively
and also you can use
if not ....
to negate a condition
or
if condition (dothis) else (dothat)
There must be a separator before the opening parenthesis of the IF true-condition target
That opening parenthesis must be on the same physical line as the if
Where an 'else' clause is used, the ending parenthesis of the "true" block, a separator and the else keyword must be on the same physical line
Where an 'else' block is used, the else keyword, a separator and the opening parenthesis of the "else" block must be on the same physical line
ie
if condition (
something
) else (
someotherthing
)
but be careful!
batch does not support floating-point. comparing 1.0 with 0.9 will be performed as an alphabetic comparison and 2.0 will be reported as greater than 19.0 (easy with not-equal...)

Batch File - How do I display a precent of a variable?

I have a batch file which must be able to display a percentage. Unfortunately I have no idea how to accomplish this.
The file takes a range of individual points from 0 to 29 and adds or subtracts points from this range in a background process the user never sees. I want the current percent of how full that range is to be displayed. IE if there are 29 points the file displays "100 %", if there are 22 points it lists "75 %", ectra.
Mathematically the operation should be (x/29)*100. I have coded this operation as:
set /a math="%shields%" / "%scap%"
set /a sm="%math%" * 100
but my code dose not function. sm is the variable which will be the percent, shields is the current 0 - 29 point value and scap is the maximum value shields can be (normally 29 but some conditions can adjust this.)
Can I get a hand with this please? Its confusing.
Matematic operation in bat don't accept floating point value if you make :
22/29 in bat you'll get 0 and 0 *100 = 0.
so you have to do (x*100)/29
#echo off
set $val=22
set /a $percent=(%$val%*100)/29
echo %$percent% %%

Resources