From: solar on 4 Sep 2009 12:58 Hi, There seems to be a bug in the way numbers are compared in Tcl. Consider the below script for calculating Pythagorean triplets. For hypotenuse upto a value of 100, there should have been 63 unique triplets. On Windows XP the script detects only 62. The script doesn't detect the case where c=99, b=20 ==> a=101. However running the same script under Tcl 8.4.1 in Cygwin detects 63 triplets. I don't have a Linux machine at hand to test it there. Following is the script and relevant output. Could anyone shed some light on the cause of this. Maybe it has something to do with how the numbers are represented internally? Running the script for N>100 shows up many more such missed values. An equivalent program in C runs correctly on the same machine. C code was compiled using both gcc and VC++6.0. ######################################################################### # a^2 = b^2 + c^2 proc pythag {MAX} { set i 0 for {set c 2} {$c <= $MAX} {incr c} { for {set b 1} {$b < $c} {incr b} { set a [expr hypot($c, $b)] ;# Calc. Hypot if { ($c == 99) && ($b == 20)} { ;# <<<<<<<< puts ">> [expr round($a)] == $a" } if {[expr round($a)] == $a} { puts "$a : $b : $c" incr i } } } return $i } if {$argc == 1} { set MAX [lindex $argv 0] } else { puts stderr "Usage: tclsh $argv0 N" exit } puts [pythag $MAX] ############# OUTPUT ################ Tcl 8.4.1 (Cygwin) ------------------------ 5.0 : 3 : 4 10.0 : 6 : 8 <snip> 104.0 : 40 : 96 120.0 : 72 : 96 >> 101 == 101.0 101.0 : 20 : 99 125.0 : 75 : 100 63 Tcl 8.4.18 (Activestate Dist.) --------------------- 5.0 : 3 : 4 10.0 : 6 : 8 <snip> 104.0 : 40 : 96 120.0 : 72 : 96 >> 101 == 101.0 125.0 : 75 : 100 62 Tcl 8.5.2 (Activestate Dist.) ---------------------- 5.0 : 3 : 4 10.0 : 6 : 8 <snip> 104.0 : 40 : 96 120.0 : 72 : 96 >> 101 == 100.99999999999999 125.0 : 75 : 100 62 ########################################### TIA --
From: Larry W. Virden on 4 Sep 2009 13:41 On Sep 4, 12:58 pm, solar <solaradmin2...(a)gmail.com> wrote: >> 101 == 100.99999999999999 From what I can tell, looking at tcl/generic/tclBasic.c and tclExecute.c, along with tclWinPort.h , Tcl is calling what appears to be the underlying C library hypot function directly. At least on Unix, that function is defined to take 2 type double arguments and returns a double return code. Here's the peculiar thing. I modified your example to ensure that the 2 arguments to hypot were truncated to be an integer. So the values passed to hypot should in my case anyways be exactly 20 and 99. The underlying function, it would seem to me, should be calculating the result as the square root of 10201. One would think that, even with the fuzziness of floating point, that the answer to that question would be 101. Apparently not, however. http://wiki.tcl.tk/879 is one of I suspect several wiki pages that discusses the dilemma of dealing with real numbers.
From: Bruce on 4 Sep 2009 14:15 Larry W. Virden wrote: > On Sep 4, 12:58 pm, solar <solaradmin2...(a)gmail.com> wrote: > >>> 101 == 100.99999999999999 > > From what I can tell, looking at tcl/generic/tclBasic.c and > tclExecute.c, along with tclWinPort.h , Tcl is calling what appears to > be the underlying C library hypot function directly. At least on Unix, > that function is defined to take 2 type double arguments and returns a > double return code. > > Here's the peculiar thing. I modified your example to ensure that the > 2 arguments to hypot were truncated to be an integer. So the values > passed to hypot should in my case anyways be exactly 20 and 99. The > underlying function, it would seem to me, should be calculating the > result as the square root of 10201. doesn't matter if the inputs are integers - the result is a double > One would think that, even with > the fuzziness of floating point, that the answer to that question > would be 101. Apparently not, however. why do you think 101 would have an exact representation in binary? > > http://wiki.tcl.tk/879 is one of I suspect several wiki pages that > discusses the dilemma of dealing with real numbers. > > > yes the may be variances in behavior accross versions of tcl and various OS's but the only "bug" I see is in the code of the script itself that is doing an exact comparison of floating point numbers. a better check would be to get the rounded result - cast to integer and then square that integer and compare it to the sum of squares of the input. (since you end up needing the sum of squares anyway, you could calc that then just use sqrt (then round, then cast, then square) instead of using hypot. or you could just change you comparison to use a suitable epsilon. Bruce
From: Kevin Kenny on 4 Sep 2009 14:40 solar wrote: > Hi, > > There seems to be a bug in the way numbers are compared in Tcl. > Consider the below script for calculating Pythagorean triplets. > For hypotenuse upto a value of 100, there should have been 63 > unique triplets. It appears that the MSVC library generates a result with an error of 1 unit in the least significant place for hypot(99.0, 20.0). There is very little that Tcl can do about bugs in the underlying C library. I'm getting seriously tired of reimplementing C library functions because the vendors can't be troubled to make them actually work. By the way, you *do* realize that there are much better ways to generate Pythagorean triples? If m and n are relatively prime, m > n, and exactly one of m and n is even, then a = mn, b = m**2 - n**2, c = m**2 + n**2 is a primitive Pythagorean triple, and all three sides can be multiplied by any integer to yield more Pythagorean triples. No square rooting or other floating point machination needed. -- 73 de ke9tv/2, Kevin
From: Robert Heller on 4 Sep 2009 15:03 At Fri, 4 Sep 2009 09:58:19 -0700 (PDT) solar <solaradmin2009(a)gmail.com> wrote: > > Hi, > > There seems to be a bug in the way numbers are compared in Tcl. > Consider the below script for calculating Pythagorean triplets. > For hypotenuse upto a value of 100, there should have been 63 > unique triplets. > > On Windows XP the script detects only 62. The script doesn't detect > the case where c=99, b=20 ==> a=101. > > However running the same script under Tcl 8.4.1 in Cygwin detects > 63 triplets. > > I don't have a Linux machine at hand to test it there. > > Following is the script and relevant output. Could anyone shed some > light > on the cause of this. Maybe it has something to do with how the > numbers > are represented internally? Not likely. I get 63 both with native linux (tcl_patchLevel = 8.4.7) and using a Tclkit.exe running under Wine (tcl_patchLevel = 8.4.12). > > Running the script for N>100 shows up many more such missed values. > An equivalent program in C runs correctly on the same machine. C code > was compiled using both gcc and VC++6.0. > > > ######################################################################### > # a^2 = b^2 + c^2 > proc pythag {MAX} { > set i 0 > for {set c 2} {$c <= $MAX} {incr c} { > for {set b 1} {$b < $c} {incr b} { > set a [expr hypot($c, $b)] ;# Calc. Hypot > > if { ($c == 99) && ($b == 20)} { ;# <<<<<<<< > puts ">> [expr round($a)] == $a" > } > > if {[expr round($a)] == $a} { *I* would suspect this line. You are comparing with *equality* a floating point number. That is often bad news. Remember, the the *computer* is using finite presision *binary* floating point numbers the results are not *mathematically* what you might expect... All it would take would be some guard bit jitter to completely ruin your day... Maybe you want (I'm suspecting that 101.0 is really 101.00000000001, which is != 101: if {[expr round($a)] == [expr {int(a)}]} { > puts "$a : $b : $c" > incr i > } > } > } > return $i > } > > if {$argc == 1} { > set MAX [lindex $argv 0] > } else { > puts stderr "Usage: tclsh $argv0 N" > exit > } > > puts [pythag $MAX] > > ############# OUTPUT ################ > Tcl 8.4.1 (Cygwin) > ------------------------ > 5.0 : 3 : 4 > 10.0 : 6 : 8 > <snip> > 104.0 : 40 : 96 > 120.0 : 72 : 96 > >> 101 == 101.0 > 101.0 : 20 : 99 > 125.0 : 75 : 100 > 63 > > Tcl 8.4.18 (Activestate Dist.) > --------------------- > 5.0 : 3 : 4 > 10.0 : 6 : 8 > <snip> > 104.0 : 40 : 96 > 120.0 : 72 : 96 > >> 101 == 101.0 > 125.0 : 75 : 100 > 62 > > Tcl 8.5.2 (Activestate Dist.) > ---------------------- > 5.0 : 3 : 4 > 10.0 : 6 : 8 > <snip> > 104.0 : 40 : 96 > 120.0 : 72 : 96 > >> 101 == 100.99999999999999 > 125.0 : 75 : 100 > 62 > ########################################### > > > TIA > -- > -- Robert Heller -- 978-544-6933 Deepwoods Software -- Download the Model Railroad System http://www.deepsoft.com/ -- Binaries for Linux and MS-Windows heller(a)deepsoft.com -- http://www.deepsoft.com/ModelRailroadSystem/
|
Next
|
Last
Pages: 1 2 3 4 5 6 Prev: how to spawn and expect multiple processes "in parallel" Next: single quote problem |