The IEEE floating point values โโ(which Tcl uses internally because they are supported by your processor hardware) know very well that they do not represent the values โโexactly. In any case, as a first approximation; they represent values โโjust like they have a fixed number of bits (64 for double , which Tcl uses), but the value they represent may be slightly different from what you think (because many values โโcannot be represented exactly in a fixed number of binary digits, like 1/3 almost ten-digit, but not exactly 0.3333333333, this is the same, but in a different number base).
Tcl takes some limited steps to resolve this issue for display; starting at 8.5, it displays floating point numbers with the minimum number of digits needed to get the exact value, and at 8.4 and before it just uses fewer digits when printing the number (up to 15 decimal digits instead of 17 what would be needed for the exact views), where it is controlled by the magic variable tcl_precision . However, do not set this variable; it does not do what you need, as it is all about rendering the value for the string, not the value itself. Instead, you need to use a different (and very well-known) equality strategy: equal-in-epsilon.
# Magic value! This one is OK for values in the range of small integers proc equal_float {ab {epsilon 1e-15}} { return [expr {abs($a - $b) < $epsilon}] }
Then you will use it as follows:
# Instead of: if {$x == 42.3} { ... } if {[equal_float $x 42.3]} { ... }
Note that this is another consequence of this: you should never use floating point numbers for iteration purposes, as this allows errors to accumulate and exceed epsilon. Instead of going from 0 to 25 in increments of 0.1, go from 0 to 250 in whole steps, and then print the float value by multiplying by 0.1.
source share