Why does Tcl think a fraction less than one is zero?

The short answer is that Tcl (like most computer languages) doesn't do fractions; it only knows about integers and floating-point numbers. Hence expr doesn't "evaluate" fractions, but the way you would ask it to compute a quotient may look like as it evaluates a fraction.

[Explain idioms of "computer arithmetic".]

Sometimes, Tcl's expression handling can be a little bit unexpected to newcomers:

 % expr 1/2
 0

This is because the above code asks for integer division (this is true in many other languages too) and that (conceptually) contains a round-down-to-int of the result. (The remainder operation, %, is often useful when you're working with integer division).

 % puts "1/2 is [expr 1/2] remainder [expr 1%2]"
 1/2 is 0 remainder 1

If you really want to end up with a half, force one of the arguments to the division operation to be a floating-point value:

 % expr double(1)/2
 0.5

See expr problems with int for more on integer division and how to avoid it.


rdt : 2005-01-27 : This is a property of integers that can take on values of 0,1,2,... and therefore have no values between 0 and 1. However:

 % expr 1.0 / 2
 0.5

show the expected value. Whereas in a calculator, most math is done in floating point, in Tcl, floating point math is only performed when you explicitly say to do so.


LH 2017-11-29 What more, fractions 1/x can also be -1, as seen in the following examples:

 % expr -1/2
 -1
 % expr 1/-2
 -1

Combine the above with

 % expr -(1/2)
 0

and you can see that integer division breaks one of the laws of arithmetics (-x)/y = x/(-y) = -(x/y). The reason for this strange behaviour of integer division is that the pair of operators / and % should satisfy the law (x/y)*y = x-(x%y), to properly handle modular arithmetics. All programming languagues I know implement integer division in this way, and so does Tcl.


GWM A quaint gotcha to beware of:

expr 225/119/84. => 0.0119047619048

while

expr 225./119/84 => 0.0225090036014

In the first case the division (225/119) is performed as integer division (giving 1) then divided by the real 84. In the second case 225./119 is floating point and divided by 84 gives the correct answer.

You can use wide to give more precision to your integers (if 64 bits is supported on your platform) however:

expr wide(225.)/119/84. => 0.0119047619048 

since the real number is cast to a long integer by wide, then integer divided as before.


Occasionally integer multiplication is hit by precision problems:

(bin) 13 % expr 12345000*100
1234500000
(bin) 14 % expr 12345000*1000
-539901888  (!!!)
(bin) 15 % expr 12345000*100000
1844386048  (!!!++)

But wide saves the day...

(bin) 16 % expr wide(12345000)*100000
1234500000000
(bin) 17 % expr 12345000*wide(100000)
1234500000000

for a bit (!!--):

(bin) 19 % expr 12345000*wide(100000)*wide(100000)*wide(100000)
4128214688309968896

AMG: I don't think the above discussion concerning integer multiplication belongs on this page. Also, it's obsolete with the addition of automatic bignums (since Tcl 8.5.x?).

GWM I use both 8.4 & 8.5 - we need to be aware that you may get different (more often correct) results with 8.5. A further example for 8.5 users:

expr 1*int(1000001000000000000000000)

% expr 12345000*1000
12345000000
% expr int(12345000*1000)
-539901888

As shown here, if you really want the old behavior, you can use int.