#1454 "if" does not evaluate same as "expr"

obsolete: 8.3
closed-invalid
nobody
5
2001-03-20
2001-03-20
Anonymous
No

The following script produces strange output.

Script:
#-----------------------------------------------
set vmin 1.3
set vmax 1.7
set idx 4
set incr 0.1

set newval [expr {$vmin+int($idx)*$incr}]

if { $newval > $vmax } {
puts "Bare 'if' says $newval > $vmax"
} else {
puts "Bare 'if' says $newval <= $vmax"
}

if { [expr $newval > $vmax] } {
puts "'if' with expr says $newval > $vmax"
} else {
puts "'if' with expr says $newval <= $vmax"
}
#-----------------------------------------------

Output:
Bare 'if' says 1.7 > 1.7
'if' with expr says 1.7 <= 1.7

As you see, the "if" command returns a different answer
depending on whether or not you use expr.

Discussion

  • Nobody/Anonymous

    Logged In: NO

    The problem seems to be that the arguments to [expr] aren't braced. I added:

    if { [expr {$newval > $vmax}] } {
    puts "'if' with braced expr says $newval > $vmax"
    } else {
    puts "'if' with braced expr says $newval <= $vmax"
    }

    and it agreed with the raw [if]. I imagine this has to do with shimmering but that's a guess. You ought to
    brace [expr] arguments for performance anyway so this doesn't seem like a real issue.

    -- Chris Nelson (chris@pinebush.com), who can't manage to log into SorceForge reliably

     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902

    This problem (a known feature of Tcl that is unlikely to
    ever be altered for a host of deep reasons) stems from the
    fact that 0.1 is not a precisely representable floating
    point number and that arguments to [expr] are [concat]enated
    before evaluation. Rerun the script with tcl_precision set
    to 17, or with the expression to pass to [expr] in {braces},
    and you'll get agreement between the "bare if" and the "if
    with expr".

    If this matters very much, use fixed-point arithmetic
    instead.

     
  • Donal K. Fellows

    • summary: "if" does not evaluate same as "expr" --> "if" does not evaluate same as "expr"
    • status: open --> closed-invalid