1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Unexpected Results from Doing Numeric Comparisons...

Discussion in 'Support' started by mathewsdw, Sep 27, 2011.

  1. mathewsdw

    Joined:
    May 24, 2010
    Messages:
    855
    Likes Received:
    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.
     

    Attached Files:

  2. Rodolfo

    Joined:
    May 20, 2009
    Messages:
    216
    Likes Received:
    0
    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
     
  3. mathewsdw

    Joined:
    May 24, 2010
    Messages:
    855
    Likes Received:
    0
    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
     
  4. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    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
     
  5. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    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
     
  6. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    10,090
    Likes Received:
    85
    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.

    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.
     
  7. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    10,090
    Likes Received:
    85
    WAD -- you can't have a unary operator for a unary operator! (@EVAL is attempting to correct an invalid operations as best it can.)
     
  8. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    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
     
  9. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    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
     
  10. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    10,090
    Likes Received:
    85
    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.)

    The documentation is wrong. It has already been corrected for 13.0.24.
     
  11. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    10,090
    Likes Received:
    85
    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)]
     
  12. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    | @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
     
  13. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    ---- Original Message ----
    From: rconn
    To: ESFabian@zenge.org
    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
     
  14. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    10,090
    Likes Received:
    85
    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".
     
  15. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    10,090
    Likes Received:
    85
    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.


    What did you think it would do? (And if nothing, why did you do it?)
     
  16. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,129
    Likes Received:
    33
    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.
     
  17. vefatica

    Joined:
    May 20, 2008
    Messages:
    8,129
    Likes Received:
    33
    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
     
  18. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    1,203
    Likes Received:
    11
    I didn't know you could do that! That's
    pretty nifty.
    -Scott

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



    to @EVAL:

     

Share This Page