TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: MeasureUp on May 31, 2013, 02:21:55 AM

Title: When Equal is not Equal...
Post by: MeasureUp on May 31, 2013, 02:21:55 AM
It is a bit strange to me:
Code: [Select]
(defun c:TEST ()
(defun DTR (deg)(* pi (/ deg 180.0)))
(defun TAN (deg)(/ (float (sin (DTR deg))) (float (cos (DTR deg)))))
(setq A 235.0)
(setq A1 (/ A (TAN 45.0)))
(setq B (getreal "B = "))
)

when I enter 235 for "B" then compare with "B" and "A1" like this:
Code: [Select]
(< B A1)
It returns "T".
What is wrong?
Your helps are much appreciated.
Title: Re: When Equal is not Equal...
Post by: Marc'Antonio Alessi on May 31, 2013, 04:49:10 AM
Maybe this is the answer:

Command: (rtos (TAN 45.0) 2 16)
"0.9999999999999998"
Title: Re: When Equal is not Equal...
Post by: fixo on May 31, 2013, 08:09:44 AM
You can also check this way
Code: [Select]
(if (< (abs (- B A1)) 0.0000001)) then equal. otherwise not
Title: Re: When Equal is not Equal...
Post by: Lee Mac on May 31, 2013, 08:32:30 AM
Consider the equal function with a tolerance to account for the rounding of doubles (http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems), e.g.:

Code - Auto/Visual Lisp: [Select]
  1. (equal a1 b 1e-8)
Title: Re: When Equal is not Equal...
Post by: MeasureUp on June 02, 2013, 07:47:25 PM
Many thanks to Marc'Antonio Alessi, fixo and Lee for pointing out the difference between B and A1.
What I can see is that the"sin" and "cos" functions are not as good as what a handheld calculator does.
For example, (rtos (sin (DTR 30)) 2 20) returns "0.4999999999999999".
Title: Re: When Equal is not Equal...
Post by: Lee Mac on June 02, 2013, 07:56:18 PM
What I can see is that the"sin" and "cos" functions are not as good as what a handheld calculator does.
For example, (rtos (sin (DTR 30)) 2 20) returns "0.4999999999999999".

The handheld calculator works in exactly the same way to calculate the value, it simply rounds the result.

Code - Auto/Visual Lisp: [Select]
  1. _$ (rtos (sin (/ pi 6.0)) 2 16)
  2. "0.5000000000000000"
  3. _$ (rtos (sin (/ pi 6.0)) 2 17)
  4. "0.4999999999999999"

Since reals in AutoLISP are represented by double-precision floating point values (http://en.wikipedia.org/wiki/Double-precision_floating-point_format) (doubles), they can hold at most 16 decimal places of precision - this is likely more than that offered by your handheld calculator.

Please re-read: Floating Point Accuracy Problems (http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems), as linked above.
Title: Re: When Equal is not Equal...
Post by: MeasureUp on June 03, 2013, 01:30:53 AM
What I can see is that the"sin" and "cos" functions are not as good as what a handheld calculator does.
For example, (rtos (sin (DTR 30)) 2 20) returns "0.4999999999999999".

The handheld calculator works in exactly the same way to calculate the value, it simply rounds the result.

Code - Auto/Visual Lisp: [Select]
  1. _$ (rtos (sin (/ pi 6.0)) 2 16)
  2. "0.5000000000000000"
  3. _$ (rtos (sin (/ pi 6.0)) 2 17)
  4. "0.4999999999999999"

Since reals in AutoLISP are represented by double-precision floating point values (http://en.wikipedia.org/wiki/Double-precision_floating-point_format) (doubles), they can hold at most 16 decimal places of precision - this is likely more than that offered by your handheld calculator.

Please re-read: Floating Point Accuracy Problems (http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems), as linked above.

Thanks Lee.
Title: Re: When Equal is not Equal...
Post by: Lee Mac on June 03, 2013, 06:15:19 AM
You're welcome.