Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

Unexpected Results from Doing Numeric Comparisons...

May
855
0
As I have mentioned many times previously, I'm trying to "replace" C++ programs by batch files whenever possible, and I had a need to do some relatively simple numeric calculations. Well, the .btm file I was writing did a comparison of one numeric value to another in a "if" statement, and I was not getting the results I expected. So, after quite a bit of experimentation, I was able to reduce it to the following (note that no batch file is involved):
HTML:
[Z:\]ver
TCC  12.11.76   Windows 7 [Version 6.1.7601]

[Z:\]If .75647374412 LT .75647374413 Echo Less Than

[Z:\]If .5647374412 LT .5647374413 Echo Less Than
Less Than

[Z:\]Echo %@Eval[.5647374412<.5647374413]
0

[Z:\]Echo %@Eval[0<.1]
0

[Z:\]Echo %@Eval[0LT.1]
TCC: Syntax error "0LT.1"

[Z:\]Echo %@Eval[0<1]
1

[Z:\]
As you can see if you examine the above closely, a "straight" comparison in an "If" statement does not work beyond 10 digits of precision (in TCMD.INI, EvalMax=14), and an expression involving @Eval does not work at all if the right operand is 0 and the left argument is a fractional value. (Although, as you can also see, comparing 0 to 1 gives the expected result.)

So to be complete about it, I did the same thing under version 12.11.74, and just to see if there was any change in version 13, I repeated things in (my trial version of) 13.00.23, again with the same results. (And "EvalMax" is "14" in all cases.) Just so there is no doubt about any of this, attached to this posting is a zip file containing the files produced by the "Save to File..." menu option for all three versions of TCC.
 

Attachments

  • NumericEvaluations.zip
    1.2 KB · Views: 276
I am using 13.00.23 and it seems to me that there are some differences if I use a dot or a comma, and if I use a leading 0 or not. So, You should check Your regional settings and Your TakeCommand settings, and do some experiments adding a leading 0. Also, I too get a syntax error for "Echo %@Eval[0LT.1]", You should use spaces before and after "LT".

Regards

Rodolfo Giovanninetti
 
I am using 13.00.23 and it seems to me that there are some differences if I use a dot or a comma, and if I use a leading 0 or not. So, You should check Your regional settings and Your TakeCommand settings, and do some experiments adding a leading 0. Also, I too get a syntax error for "Echo %@Eval[0LT.1]", You should use spaces before and after "LT".

Regards

Rodolfo Giovanninetti
Thank you Rodolfo, but I tried all of your suggestions, alone and in combination, and none of them changed the result at all. And I did all of this Version 13.00.23. So I am still back to where I started. (And all indications are that a comma is, in fact, the thousands separator, and a dot is the decimal separator, which is as it should be.)

Dan Mathews
 
From: Rodolfo
| I am using 13.00.23 and it seems to me that there are some
| differences if I use a dot or a comma, and if I use a leading 0 or
| not. So, You should check Your regional settings and Your TakeCommand
| settings, and do some experiments adding a leading 0. Also, I too get
| a syntax error for "Echo %@Eval[0LT.1]", You should use spaces before
| and after "LT".

LT LE etc. are valid only where "conditional expressions" are acceptable. @EVAL accepts only the less than (<) and greater than (>) signs, and the result is documented only in the "What's new" section of the V10 help file (last revised 2009-07-25): TRUE is 1, FALSE is 0.

I performed more detailed testing (WinXP home SP3, TCC 13.0.23) of the "<" operator, using each possible combination of the strings in the list below as first and second parameter: -1 -1.0 -.1 -0.1 0 .1 0.1 +.1 +0.1 1 1.0 +1 +1.0. The results are consistent with both parameters being truncated to integer toward zero before the comparison is performed.

In additional testing I also discovered other discrepancies between the documentation and the operation of the @EVAL function. According to the documentation, -%x ought to be interpreted as the "negation of symbolic parameter", i.e., same as multiplication with -1. However, try the following:

[C:]> set m=+1 %+ echo %@eval[-%m]
1
[C:]>for /l %n in (-2,1,2) echo %n %@eval[-%n]
-2 -2
-1 -1
0 0
1 -1
2 -2

Notice that the unary minus (-) operator only affects parameters that do not have an explicit sign character. This explains why some of my batch programs returned unexpected results (which at the time I had considered to be my mistake and had worked around).
--
Steve
 
From: mathewsdw
| And all indications are that a comma is, in fact, the thousands
| separator, and a dot is the decimal separator, which is as it should
| be.

I never found any problem from those separators. However, I believe Rodolfo's setting is the opposite of yours, hence the suggestion.
--
Steve
 
[Z:\]If .75647374412 LT .75647374413 Echo Less Than

The IF tests (which are string tests, not numeric tests) are limited to a maximum of 10 decimal places when IF decides to try the test as numeric instead of ASCII.

If you're doing complex numeric comparisons, you should be doing them in @EVAL instead of having IF try to interpret them.

[Z:\]Echo %@Eval[0LT.1]
TCC: Syntax error "0LT.1"

Not surprising, as you've invented some imaginary syntax here. There is no "LT" operator in @EVAL.

The > and < operators only work with integers, not floating point. If you want to compare floating point numbers, subtract and test the result.
 
From: rconn
| Originally Posted by mathewsdw
| [Z:\]If .75647374412 LT .75647374413 Echo Less Than
|
| The IF tests (which are string tests, not numeric tests) are limited
| to a maximum of 10 decimal places when IF decides to try the test as
| numeric instead of ASCII.

This limitation should be documented.

| If you're doing complex numeric comparisons, you should be doing them
| in @EVAL instead of having IF try to interpret them.

Contradicts how < and > operate (below).

| The > and < operators only work with integers, not floating point.

They are listed under the heading "Operators accepting fractional parameters". They should instead be under the heading "Operators which truncate parameters to integer".

| If you want to compare floating point numbers, subtract and test the result.

No such suggestion anywhere in HELP. I think a new topic "Numeric operations" is warranted.
--
Steve
 
From: rconn
| Originally Posted by Steve Fabian
|| Notice that the unary minus (-) operator only affects parameters that
|| do not have an explicit sign character.
|
| WAD -- you can't have a unary operator for a unary operator! (@EVAL
| is attempting to correct an invalid operations as best it can.)

I thought @EVAL is a number processor. If it evaluated the parameter of the unary operator as a positive or negative number, before applying the operator the documentation would match the operation and what the same operator means in algebra, where prefixing a variable's name with the minus sign is equivalent to multiplying by -1.
--
Steve
 
| The IF tests (which are string tests, not numeric tests) are limited
| to a maximum of 10 decimal places when IF decides to try the test as
| numeric instead of ASCII.

This limitation should be documented.

I'm not a strong believer in documenting extremely obscure limitations that arise once every 20 years. (Especially since 99.9% of the users won't find it in the docs anyway.)

They are listed under the heading "Operators accepting fractional parameters".

The documentation is wrong. It has already been corrected for 13.0.24.
 
I thought @EVAL is a number processor. If it evaluated the parameter of the unary operator as a positive or negative number, before applying the operator the documentation would match the operation and what the same operator means in algebra, where prefixing a variable's name with the minus sign is equivalent to multiplying by -1.

Sure, if I throw out 10,000 lines of existing @EVAL code and rewrite it as an RPN calculator. (But then there's that pesky problem with breaking every existing alias and batch file again ...)

@EVAL is a left-to-right interpreter. IMHO it doesn't seem like a cruel and arbitrary restriction to expect correct syntax. The variable is going to be expanded before the numeric parser sees it, so @EVAL is not going to see "-%a", it's going to see "--1". Are you trying to decrement 1, or are you applying an invalid unary operator to another unary operator?

If you're bound and determined to apply two consecutive unary operators (and if you are, I'd really like to see a real world example of why this is necessary!), you can use the correct syntax:

echo %@eval[-(%a)]
 
| @EVAL is a left-to-right interpreter. IMHO it doesn't seem like a
| cruel and arbitrary restriction to expect correct syntax.

As long as it is clear that @EVAL[] has a syntax that's different from the standard syntax of algebra, and the one needed here is explicitly defined.

| The variable is going to be expanded before the numeric parser sees it,
| so @EVAL is not going to see "-%a", it's going to see "--1".

That's the problem. It sees the string, not the numeric value, unless it was "set /a" .

| Are you
| trying to decrement 1, or are you applying an invalid unary operator
| to another unary operator?

Fair question - if dealing with strings, but not if dealing with numbers.

| If you're bound and determined to apply two consecutive unary
| operators (and if you are, I'd really like to see a real world
| example of why this is necessary!), you can use the correct syntax:
|
| echo %@eval[-(%a)]

Just remember the formula for solving the quadratic equation ax**2+bx+c=0:

x=(-b+-sqrt(b**2-4ac))/2a

(did not use pure algebraic notation, don't think it would survive both Outlook Express and the forum software).
In the formula b may be a negative number! How would you represent this formula using @EVAL[]?

BTW, the corollary to %@eval[-(%a)] using plus sign: %@eval[+(%a)] returns the absolute value of %a, regardless of its actual value. I don't believe that to be WAD...
--
Steve
 
---- Original Message ----
From: rconn
To: [email protected]
Sent: Tuesday, 2011. September 27. 09:45
Subject: RE: [Support-t-3243] Re: Unexpected Results from Doing Numeric
Comparisons...

| Quote:
| Originally Posted by Steve Fabian
|| The IF tests (which are string tests, not numeric tests) are limited
|| to a maximum of 10 decimal places when IF decides to try the test as
|| numeric instead of ASCII.
|
| This limitation should be documented.
|
| I'm not a strong believer in documenting extremely obscure
| limitations that arise once every 20 years. (Especially since 99.9%
| of the users won't find it in the docs anyway.)

That's why I suggested a new topic. It could cover many aspects, including number formatting, simplifying its repeated descriptions in PDIR, @FORMATN, etc.

| Quote:
| They are listed under the heading "Operators accepting fractional
| parameters".
|
| The documentation is wrong. It has already been corrected for 13.0.24.

Thanks!
--
Steve
 
> In the formula b may be a negative number! How would you
> represent this formula using @EVAL[]?

By using the correct syntax and not using %'s in the expression, so @EVAL
sees the original expression and not one pre-expanded by the TCC parser.


> BTW, the corollary to %@eval[-(%a)] using plus sign:
> %@eval[+(%a)] returns the absolute value of %a, regardless of
> its actual value. I don't believe that to be WAD...

What did you think it would do? (And if nothing, why did you do it?)
 
On Tue, 27 Sep 2011 10:27:20 -0400, Steve Fabian <> wrote:

|In the formula b may be a negative number! How would you represent this formula using @EVAL[]?

Code:
v:\> function quad
%@eval[((-1) * (%2) + ((%2) ** 2 - 4 * (%1) * (%3)) ** .5) / (2 * (%1))] , 
%@eval[((-1) * (%2) - ((%2) ** 2 - 4 * (%1) * (%3)) ** .5) / (2 * (%1))]

v:\> echo %@quad[1,-2,-3]
3 , -1

It works as well if you leave out all the spaces.
 
On Tue, 27 Sep 2011 10:27:20 -0400, Steve Fabian <> wrote:

|In the formula b may be a negative number! How would you represent this formula using @EVAL[]?

Code:
v:\> function quad
%@eval[((-1) * (%2) + ((%2) ** 2 - 4 * (%1) * (%3)) ** .5) / (2 * (%1))] , 
%@eval[((-1) * (%2) - ((%2) ** 2 - 4 * (%1) * (%3)) ** .5) / (2 * (%1))]

v:\> echo %@quad[1,-2,-3]
3 , -1
It works as well if you leave out all the spaces.

As with %defines in "C", it's not a bad idea to do this (below); if you remembered to do that, the function itself could be simpler.

Code:
v:\> set a=(1)

v:\> set b=(-2)

v:\> set c=(-3)

v:\> echo  %@quad[%a,%b,%c]
 3 , -1
 
I didn't know you could do that! That's
pretty nifty.
-Scott

rconn <> wrote on 09/27/2011
10:28:08 AM:


> Quote:
>
> Originally Posted by rconn [image removed]
> echo %@eval[-(%a)]
>
> I should also point out that the alternate correct syntax for @EVAL


> would be to *not* use the unnecessary %, so that the TCC parser
> won't substitute the value of "a" before passing the argument
to @EVAL:

>
> set a=-1
> echo %@eval[-a]
>
> will return "1".
>
>
 

Similar threads

Back
Top