Re: for problem...
From: Robert Heller (heller_at_deepsoft.com)
Date: 11/29/03
- Next message: cfk: "Hex Puzzlement (take 2)"
- Previous message: Laurent Riesterer: "Re: Generating the RAW ethernet packets"
- In reply to: David Cobac: "Re: for problem..."
- Next in thread: Donald Arseneau: "Re: for problem..."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sat, 29 Nov 2003 22:03:44 +0000
David Cobac <david.cobacNOSPAM@invalid.free.fr>,
In a message on 29 Nov 2003 18:13:01 +0100, wrote :
DC> Robert Heller <heller@deepsoft.com> a écrit :
DC> >Removing the braces (in this case) should not make any difference. The
DC> >braces don't have anything to do with the problem at hand. I suspect
DC> >that the 'someone in fr.comp.lang.tcl' is using a different processor
DC> >(with a different FPU) or something.
DC>
DC> Ah...i've tried it and :
DC>
DC> (david) 101 % for {set k 0} {$k<=1} {set k [expr $k+0.01]} {puts $k}
DC> 0
DC> 0.01
DC> ...
DC> 0.98
DC> 0.99
DC> 1.0
DC> (david) 101 % for {set k 0} {$k<=1} {set k [expr {$k+0.01}]} {puts $k}
DC> 0
DC> 0.01
DC> ...
DC> 0.98
DC> 0.99
I'm guessing it is in the details of when the byte compiler does its
thing and when it binds the variables and constants as floating point
numbers and expressions. This causes a small difference in the amount
of roundoff error that shows up. The error is small, but accumulates
and effects the final results in an inconsistent manor.
Try these two:
for {set k 0} {$k<=1} {set k [expr $k+0.01]} {puts [format %20.18lf $k]}
and
for {set k 0} {$k<=1} {set k [expr {$k+0.01}]} {puts [format %20.18lf $k]}
For a clue about what is happening off in roundoff land.
An important thing to notice is that k is NOT going from 0 to 1.0 by
exactly 0.01, but is actually has a 'slightly' different increment,
since '0.01' is never an exact value. This error shows up when you
format the results with a large number of digits of precision. This is
in the *nature* of floating point operations. For an operation like
this, floating point ops are notoriously suspect and create these sorts
of problems and should be avoided. Writing the loop as:
for {set ik 0} {$ik <= 100} {incr ik} {
set k1 [expr {double($ik) * .01}]
set k2 [expr double($ik) * .01]
puts [format {with braces: %20.18lf, without braces: %20.18lf} $k1 $k2]
}
will always give consistent results, with the roundoff error 'contained'
in a predictable fashion. This is because the increment is an integer
and is *exact*. The imprecision is introduced at the last possible
moment in the code. The longer you can defer this imprecision and/or
roundoff error the more accurate and 'correct' your results will be.
It is a very important programming lesson to understand the nature and
*limitations* of floating point operations. Floating point operations
are almost never *exact* -- that is never the point. Floating point
numbers are used when the *range* of the values exceeds the range
possible with integer (fixed point) numbers *AND* exact precision can
be traded off. It is generally always better to use integers (possibly
scaled), when the range is limited and an exact result is needed. Some
languages (such as Common Lisp) have an indefinite precision integers
(bignums). Common Lisp also has 'rational numbers', which are stored
as pairs of numbers, such as 1,3 for 1/3, which allows a way to exactly
represent fractions, without the problems you are seeing. I don't know
if there is a Tcl extension that implements 'bignums' or 'rational
numbers'. Generally, in specific cases one can program around the
imprecision of floating point numbers. In the specific case you are
using, the range of the numbers (0.0 through 1.0 by .01) is small
(exactly 101 values), so neither bignums nor floating point numbers are
actually needed. Using integers here makes sense and gives the most
exact results.
DC>
DC> --
DC> cordialement
DC> david cobac
DC>
\/
Robert Heller ||InterNet: heller@cs.umass.edu
http://vis-www.cs.umass.edu/~heller || heller@deepsoft.com
http://www.deepsoft.com /\FidoNet: 1:321/153
- Next message: cfk: "Hex Puzzlement (take 2)"
- Previous message: Laurent Riesterer: "Re: Generating the RAW ethernet packets"
- In reply to: David Cobac: "Re: for problem..."
- Next in thread: Donald Arseneau: "Re: for problem..."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|