From: jzakiya Date: 2009-12-23T16:15:08+09:00 Subject: Re: Trig value errors On Dec 23, 12:42 am, Phrogz wrote: > On Dec 22, 10:07 pm, Phrogz wrote: > > > irb(main):004:0> x = cos(onedegree/1e06) > > => 1.0 > > irb(main):005:0> x - 1.0 > > => -1.11022302462516e-16 > > irb(main):006:0> puts "%.30f" % x > > 0.999999999999999888977697537484 > > As an interesting and related aside, I wanted to find out what the > correct value for this calculation was (to a certain number of > decimals). I thought asking Alpha would be an easy place to start. > > This query (which has the parameter off by a factor of 1000) works:http://www.wolframalpha.com/input/?i=cos%28+2*pi+%2F+360+%2F+1e3+%29 > and results in: > 0.9999999998476912901 > > Trying for smaller parameter values, however, results in Alpha giving > up:http://www.wolframalpha.com/input/?i=cos%28+2*pi+%2F+360+%2F+1e4+%29 > (For me, that query always results in a message: "This Wolfram|Alpha > server is temporarily unavailable.") You are correct, arithmetically: 2*PI/360 => 0.0174532925199433 # equiv to 1.0 degree I incorrectly wrote in the post the value for: 2*PI/260 => 0.0241660973353061 # equiv to 1.38 degree This didn't nullify THE POINT I illustrated, which was using an increasingly smaller angle approaching zero as an argument, it eventually produced a value of '1' for cos, but not '0' for the same sin angle, as it should. I feel I've made my points as clear as I think is needed. If it doesn't bother you that the present implementation produces incorrect results for clearly unambiguous situations then we just have different standards for the need to adhere to mathematical rigor and produce exact results. BUT THAT IS A CHOICE THAT HUMANS MAKE, AND IS NOT MANDATED BY NATURE. Again, one really simple fix to eliminate these ERRORS is to do something like the following in the Math module. rename current functions as follows: cos > cosine; sin > sine, tan > tangent then redefine old aliases so that: def cos(x); cosine(x).abs < 1e-11 ? 0.0 : cosine(x) end def sin(x); sine(x).abs < 1e-11 ? 0.0 : sin(x) end def tan(x); sin(x)/cos(x) end If you want define: TRIG-EPSILON = 1e-11, or whatever, so you can change it easily and make it available. With these simple changes you even get the added benefit that tan(PI/2) => Infinity as it should (1/0), instead of currently tan(PI/2) => 1.63317787283838e16