0

I am just starting to learn TCL. On its Tutorial page, there is a part of description as the following:

1.2 / 0.1 results in 11.999999999999998, not 12. That is an example of a very nasty aspect of most computers and programming languages today: they do not work with ordinary decimal fractions, but with binary fractions. So, 0.5 can be represented exactly, but 0.1 can not.

I don't know what exactly this means. I have tried the followings:

% expr {1.2 / 0.1}
11.999999999999998
% expr {1.2 / 0.5}
2.4
% expr {1.2 / 0.4}
2.9999999999999996
% expr {1.2 / 0.3}
4.0

Like it describes, 1.2 / 0.5 will give the exact answer. But with 0.1 as divisor, it won't.

Could anyone kindly explain what the mechanism is here? Thanks.

S. Li
  • 767
  • 1
  • 7
  • 14
  • 2
    Possible duplicate of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Some programmer dude Aug 04 '18 at 13:57
  • 1
    Note that this is not a specific fault of TCL. Computers are designed this way so all languages that use floating point numbers have this issue. This is why in some situations such as financial calculations the only correct way to do math is with integers (you just do calculations on cents instead of dollars then only convert to human readable form when you want to print results) – slebetman Aug 04 '18 at 15:38

3 Answers3

3

In short, this is not a Tcl specific issue but rather a consequence of representing decimal numbers using binary digits.

A wikipedia article is here. And here is an even more detailed explanation.

Marijan
  • 136
  • 3
1

Now, that you know that is not specific to Tcl, you might still want to explore ways forward when programming in Tcl. An educating start is exactexpr provided by math::exact module of tcllib

To pick up your example:

package req math::exact
namespace import math::exact::*
set a [[exactexpr {12/10}] ref]
set b [[exactexpr {1/10}] ref]
set c [[exactexpr {$a / $b}] ref]
$c asFloat 8; # returns '1.2e1'
$a unref; $b unref; $c unref;
mrcalvin
  • 3,291
  • 12
  • 18
1

https://wiki.tcl.tk/1650

As of Tcl 8.5, changing $tcl_precision to a value other than its default value of 0 is deprecated. If you need to control the display precision of floating point values, use format (eg format %.12g $x).

% set tcl_precision 12
12
% set a [expr 1.00000000000123]
1.0
% set b [expr 1.0]
1.0
% expr { $a == $b }
0
% expr { $a eq $b }
1
Roman Kaganovich
  • 618
  • 2
  • 6
  • 27
  • This is analogous to the original question in that this is not the fault of tcl_precision!. You simply should not be doing exact comparisons on floating point numbers. – Donald Arseneau Sep 15 '20 at 00:46