0

Why is having a string value greater than (GTR) or greater or equal than (GEQ) a number always return the value true?

For example this:

Set var=abc

if %var% gtr 0 echo true

or

if %var% geq 0 echo true

No matter what "var" the number of comparison is, the result is the same. Why?

Also why is using LSS or LEQ (Less than, Less or Equal than) the result is always false?

I wanted to create a simple script only allowing numeric values up to 31 and only one letter like this:

:MENU
CLS
echo. Insert Day or "X" to return to another script
Set /p variable=Insert date:

for /f "delims=0123456789" %%a in ("%variable%") do set variable=%%a

if not defined %variable% goto :MENU
if /i %variable% equ X goto :otherscript2

if %variable% equ 0 goto :MENU
if %variable% gtr 31 goto :MENU

:: Continue script
.
.

Using this script, whenever the number is between 1-31, it will continue, if there are letters, it will return to :MENU but if it's X then it goes to :otherscript2. It's working as intended and I figured out it is because of the

  if %variable% gtr 31 goto :MENU

which means

  if <string> gtr 31 goto :MENU // where <string> = any string except the X

But I don't understand why it works like this.

Thank you in advance.

JaJe
  • 3
  • 4
  • 1
    The character `a` has got a higher code (`0x61`) than the zero `0` (`0x30`); as soon as both parts of the comparison are purely numeric, then their value are compared (given that you do not use the comparison operator `==` which forces string comparison)... – aschipfl Nov 30 '19 at 15:25
  • Thank you very much! However, adding multiple letters such as aaa, like 0x61 0x61 0x61 won't sum the total number to 183? same for the number 0000000000, 0x30 * 10 = 300 ? – JaJe Nov 30 '19 at 15:37
  • 1
    @JaJe no. See `if /?`, a numeric value is done only if both operands are numbers only *if both string1 and string2 are both comprised of all numeric digits*. Otherwise a normal [lexicographic comparison](https://en.wikipedia.org/wiki/Lexicographical_order) is done, and since `a` has larger ASCII value than `0`, `abc` will be sorter after `3` lexicographically – phuclv Nov 30 '19 at 15:49
  • 1
    String comparison does not add up character codes; rather it compares the code of the first char., if they equal, then the second char. is compared, and so on, until there is a difference; also regard that a longer string is considered as greater, so `abc` is greater than `ab`... – aschipfl Nov 30 '19 at 16:29
  • 2
    @aschipfl - Actually cmd.exe does not collate by the code value. For example, `a` (0x61) < `A` (0x41) < `b` (0x62). There are additional characters between `A` and `b`, for example `ª` (0xA6). I'm not sure if/where the full collation sequence is documented. – dbenham Nov 30 '19 at 22:19
  • 1
    I suggest to read my answer on [Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files](https://stackoverflow.com/a/47386323/3074564). It explains very detailed how string comparisons are done by command __IF__. See also [weird results with IF](https://stackoverflow.com/a/49601468/3074564) with C code demonstrating how command __IF__ compares numbers and strings. – Mofi Nov 30 '19 at 22:21
  • I see, @dbenham, thanks for the clarification! So it seems `/I` has no effect on operators other than `==`? I assume comparison results also depend on the current code page when it comes to the extended character range, that is, codes > 0x7F; can you confirm that? Anyway, I will do some experiments to find out and share my findings then -- perhaps as an answer here, or in a new thread... – aschipfl Dec 01 '19 at 10:26
  • 1
    @aschipfl - Actually the `/I` option does work with all of the comparison operators. Mofi's linked answer is worded awkwardly in a way that implies it does not work, but I believe he meant the `/I` option is ignored if doing a numeric comparison. Yes, the code page can influence how an incoming character is interpreted, but once in memory, all strings are Unicode. Environment variables are also stored as Unicode, so the code page has no influence when expanding an environment value. – dbenham Dec 01 '19 at 13:33

1 Answers1

-1

When a string and a number is compared using this syntax (if string compare-op number statements) the comparison is done using ascii code of the first character. In your first example you showed:

set var=abc
if %var% gtr 0 echo True

Here the first character of the string abc is a. ASCII code of a is 65. It is greater than 0. So it returns True. To learn more about ascii codes visit https://ee.hawaii.edu/~tep/EE160/Book/chap4/subsection2.1.1.1.html.

And your code works becuase the ascii code of X and other characters is greater than 31 which is explained up.