Jump to content
Sign in to follow this  
Eigensheep

Problems with trigonometry

Recommended Posts

Eigensheep

I really hope someone can explain this.

When using the Sin and Cos functions, it seems perfectly natural to write:

$pi = 4 * ATan(1)
$degToRad = $pi / 180
$x = Sin(180 * $degToRad)

But this produces some really weird results. And I've worked out that it's not the $degToRad variable because Sin($pi) also produces 1.22460635382238e-016. (For those of you who didn't know, it should be 0) I get similar results for the following:

Sin(360 * $degToRad) shows -2.44921270764475e-016

Cos(90 * $degToRad) shows 6.12303176911189e-017

And a few others. In short, any trigonometric function that gives a result of 0 actually produces a random and incredibly small non-zero number. Explanations?

Share this post


Link to post
Share on other sites
monoceres

Hi!

I always use the _Radian() function in the math UDF to get everything right.

And as you can see in this example, Sin(360 degrees) returns zero:

#include <math.au3>
$x = Sin(_Radian(360))
MsgBox(0,"",$x)

:)


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites
Eigensheep

Thanks for the reply, and I like the idea, i'll make sure I do that, but I still get this even with your script:

Posted Image

I'm thinking, maybe it's my autoit version? I've got 3.2.8.1 so i'm going to get the latest version now.

Share this post


Link to post
Share on other sites
martin

Thanks for the reply, and I like the idea, i'll make sure I do that, but I still get this even with your script:

Posted Image

I'm thinking, maybe it's my autoit version? I've got 3.2.8.1 so i'm going to get the latest version now.

It isn't anything to do with the AutoIt version, it's a limitation of digital computers.

2 * 10^-16 is pretty small and most people would not be working to 15 decimal places. It's like measuring the distance to the sun to an accuracy of less than the thickness of a hair.

$pi = 4 * ATan(1)
$degToRad = $pi / 180
$x = Sin(180 * $degToRad)
ConsoleWrite("Answer = " & Round($x ,15) & @CRLF)

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites
monoceres

It isn't anything to do with the AutoIt version, it's a limitation of digital computers.

2 * 10^-16 is pretty small and most people would not be working to 15 decimal places. It's like measuring the distance to the sun to an accuracy of less than the thickness of a hair.

$pi = 4 * ATan(1)
 $degToRad = $pi / 180
 $x = Sin(180 * $degToRad)
 ConsoleWrite("Answer = " & Round($x ,15) & @CRLF)
I still think it's weird because this:

#include <math.au3>
$x = Sin(_Radian(0))
MsgBox(0,"",$x)

Is returning zero and 360 is exactly the same since sin has a period of 360 degrees


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites
BAM5

If you would really like to make your way work you should add some message boxes with the values the variable returns after each step. This is what I do to find out what went wrong in my applications.


[center]JSON Encoding UDF[/center]

Share this post


Link to post
Share on other sites
Eigensheep

@martin

sorry for the delay, yea, it could be that, but the round function won't completely rectify the situation as the error gets larger with the angle so less decimals are accurate. You need to find the smallest match so that x<360.

For anyone who cares this does the job quite nicely and can be modified for radians:

#include <Math.au3>
$angle = Smallest360($angle)
$pi = 4 * ATan(1)
$result = Sin(_Radian(720))
MsgBox(64,"Result",$result)

Func Smallest360($number)
    ParamCheck($number)
    $div = $number / 360
    $times = Int($div)
    $subt = $times * 360
    $result = $number - $subt
    Return $result
EndFunc

(edit:)

@monoceres

Sin(0) is returning 0 because the algorithm (probably CORDIC if you really care) doesnt actually do anything to get a value for 0 (look up the Taylor expansion + youll see what I mean) so only multipes of 180 above 0 will incur an error.

Edited by logicBird

Share this post


Link to post
Share on other sites
Xand3r
Func Smallest360($number)
    ParamCheck($number)
    $div = $number / 360
    $times = Int($div)
    $subt = $times * 360
    $result = $number - $subt
    Return $result
EndFuncoÝ÷ Ûú®¢×¬jez¶§vÉW«fjV³Ê«²ÏnÜ,¯'è®Ø^¡÷í¢jëh×6Func smallest360($number)
    If $number<360 Then Return $number
    Return smallest360($number-360)
EndFunc
Edited by TheMadman

Only two things are infinite, the universe and human stupidity, and i'm not sure about the former -Alber EinsteinPractice makes perfect! but nobody's perfect so why practice at all?http://forum.ambrozie.ro

Share this post


Link to post
Share on other sites
martin

Func smallest360($number)
    If $number<360 Then Return $number
    Return smallest360($number-360)
EndFunc

Smaller and faster

Func smallest360(ByRef $numb);corrected parameter after SmOke_N pointed out mistake
 While $numb > 360
    $numb -= 360
 WEnd
EndFunc

@logicBird

I think you meant this

#include <Math.au3>
$angle = 720
$angle = Smallest360($angle)
$pi = 4 * ATan(1)
$result = Sin(_Radian($angle))
MsgBox(64,"Result",$result)

Func Smallest360($number)
 ; ParamCheck($number)
    $div = $number / 360
    $times = Int($div)
    $subt = $times * 360
    $result = $number - $subt
    Return $result
EndFunc

But it doesn't affect the example you gave when $angle = 180.

Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites
SmOke_N

Smaller and faster

Func smallest360(ByRef $num)
 While $numb > 360
    $numb -= 360
 WEnd
EndFunc
Typo it seems, $numb (unless global) isn't the variable in the param :) .

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites
martin

Typo it seems, $numb (unless global) isn't the variable in the param :) .

The variable $numb was probably just the state of my brain.

Thanks SmOke_N, I'll correct it.

Then I'm going to bed.

Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×