Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

expr problem 1

Status
Not open for further replies.

marsd

IS-IT--Management
Apr 25, 2001
2,218
US
Hi all.

I have a procedure that acts as a calculator.
For multiplication ,addition and subtraction
it works well...The guts of the procedure is:

for {set r $num} {$r < [llength $sumlist]} {incr r} {
set sum [expr $sum == 0 ? [lindex $sumlist $r] : [expr $sum * [lindex $sumlist $r]]]
r_calc $sumlist $op $sum [expr $r + 1]
}

#main()
set a(1) [r_calc {12 54 67 89 2} / 0 0]
set a(2) [r_calc {32 45 12} + 0 0]
set a(3) [r_calc {43 56 78} - 0 0]

b_parray a
#end

The output of this sample:
a(1) = 2
a(2) = 89
a(3) = -91

a(1) should be something like 1.86334e-05 according
to a calculator.

Anybody know what the issue is?
 
Well, I'm having a bit of difficulty following the evaluation of your code because I think you truncated it a bit too much. But my suspicion, based on your description of the problem, is that you're tripping over expr's preference for doing integer math whenever possible. If both operands are integers, expr performs integer math; if at least one is floating-point, expr performs floating-point math. Some examples:

[tt]% expr { 4 / 3 }
1
% expr { 4.0 / 3 }
1.33333333333
% set x 7; set y 3
3
% expr { $x / $y }
2[/tt]

The best way to force expr to perform floating-point math is to use its built-in double() function on one of the operands to force its interpretation as a floating-point value. For example:

[tt]% expr { double(4) / 3 }
1.33333333333
% expr { double($x) / $y }
2.33333333333[/tt]

Hope this helps! - Ken Jones, President, ken@avia-training.com
Avia Training and Consulting, 866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax
 
Yeah, that was the whole problem.
I'd previously used double, but in this way:
set sum [expr $sum == 0 ? [lindex $sumlist $r] : [expr double($sum / [lindex $sumlist $r])]], and had the same problem. Using your example it
works.
Thanks
 
Yes, it's a very common mistake to make. In case there are others reading this thread and not seeing the problem, double() didn't work the way marsd first tried it because he put it around the entire expression:

[tt]expr double([ignore]$sum / [lindex $sumlist $r][/ignore])[/tt]

So, expr evaluated what was inside the parentheses first -- doing the (integer) division -- and then converting the result of the division to floating-point. - Ken Jones, President, ken@avia-training.com
Avia Training and Consulting, 866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top