TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: MeasureUp on July 31, 2017, 11:31:23 PM

Title: A Bug or Not A Bug
Post by: MeasureUp on July 31, 2017, 11:31:23 PM
(setq number1 (getreal "\n\nGet Number: "))
If "number1" = 5.123, then both (/= number1 5.123) and (= (fix (* number1 1000)) 5122) are true.

Can you please explain?
Thanks in advance.

My version: AutoCAD mech 2016
Title: Re: A Bug or Not A Bug
Post by: Tharwat on August 01, 2017, 12:51:33 AM
Hi,

Should try it with equal function since you have decimal numbers with fuzz in this case.

Code - Auto/Visual Lisp: [Select]
  1. (equal number1 5.123 1e-4)
Title: Re: A Bug or Not A Bug
Post by: MeasureUp on August 01, 2017, 01:09:08 AM
Thank you for your reply.

But why the follow also returns true?
When number1 = 5.12
(= number1 5.12) = T
(= (fix (* number1 100)) 512) = T

These really confuse me.
Title: Re: A Bug or Not A Bug
Post by: kdub_nz on August 01, 2017, 02:38:47 AM
Thank you for your reply.

But why the follow also returns true?
When
(setq number1 5.12)
(= number1 5.12) = T
(= (fix (* number1 100)) 512) = T

These really confuse me.

What would you expect the result to be ?
what is confusing for you ?
Title: Re: A Bug or Not A Bug
Post by: MeasureUp on August 01, 2017, 02:51:23 AM
I was comparing with (fix (* number1 1000)) and 5123 when number1 is 5.123
I find that (= (fix (* number1 1000)) 5123) doesn't return true but (= (fix (* number1 1000)) 5122) is true.

As I also mentioned, the above comparison is no problem when number1 is 5.12
Title: Re: A Bug or Not A Bug
Post by: kdub_nz on August 01, 2017, 03:51:01 AM
Works for me

added :
using 2017 for this test.

Title: Re: A Bug or Not A Bug
Post by: roy_043 on August 01, 2017, 04:09:17 AM
There seem to be not just one but two issues here:
1.
Reals are not stored in the decimal format. Not every decimal number can be exactly translated to a floating point real (https://en.wikipedia.org/wiki/Double-precision_floating-point_format). This is where the fuzz argument of the equal function comes in.
2.
The getreal function can have a 'mind of its own'?
Code: [Select]
(defun c:test ( / str num)
  (setq str (getstring "\nNumber as string: "))
  (setq num (getreal "\nNumber as real: "))
  (- (read str) num)
)
If 5.123 is entered twice:
BricsCAD V14 32 and 64 bit: Returns 8.88178e-016
BricsCAD V16 64 bit: Returns 0.0

The second issue is new to me.
Title: Re: A Bug or Not A Bug
Post by: MeasureUp on August 01, 2017, 07:15:32 PM
Thanks to Kerry & Roy.

I noticed Roy's explanation. Let me restate the issue:

If (setq number1 (getreal "\n\nInput A Real: ")) and 5.123 was entered
(= number1 5.123) returns "nil"
(= (fix (* number1 1000)) 5123) returns "nil"

Instead of "getreal" function, I set (setq number1 5.123), then
(= number1 5.123) returns "T"
(= (fix (* number1 1000)) 5123) returns "T"

On the other hand, if (setq number1 (getreal "\n\nInput A Real: ")) and 5.12 was entered, or simply set (setq number1 5.12)
(= number1 5.12) always returns "T"
(= (fix (* number1 1000)) 512) always returns "T"


A Bug or Not A Bug?
Title: Re: A Bug or Not A Bug
Post by: kdub_nz on August 01, 2017, 08:08:49 PM

If (setq number1 (getreal "\n\nInput A Real: ")) and 5.123 was entered
(= number1 5.123) returns "nil"
(= (fix (* number1 1000)) 5123) returns "nil"

< ... >

In this case , to test getreal equality use the equal function and declare a fuzz factor

Code - Auto/Visual Lisp: [Select]
  1. (equal number1 5.123 1e-4)
Title: Re: A Bug or Not A Bug
Post by: MeasureUp on August 02, 2017, 09:01:19 PM
Hi Kerry, thank you again.

Obviously, a fuzz factor solves the problem.

However, it seems not to be logical in practice.
If (setq number1 (getreal "\n\nInput A Real: ")) and 5.123 was entered, we all can tell the value of "number1" is exactly same as 5.123
The introduction of fuzz factor to the comparison (equal number1 5.123 fuzz) seems not making sense, logically.
Furthermore, to the examples given in my reply post #7 or examples just retested below, when does user insert the fuzz factor?

I am still wondering if there is a "practical" workaround for this issue.

= = = = = = = = = = = = = = = = =
BTW I retest the following examples.
(1) 5.12
If (setq number1 (getreal "\n\nInput A Real: ")) and 5.12 was entered, or simply set (setq number1 5.12)
(= number1 5.12) always returns "T"
(= (fix (* number1 1000)) 512) always returns "T"

(2) 5.123 - This is the only problematic case.
If (setq number1 (getreal "\n\nInput A Real: ")) and 5.123 was entered
(= number1 5.123) returns "nil"
(= (fix (* number1 1000)) 5123) returns "nil"

Instead of "getreal" function, I set (setq number1 5.123), then
(= number1 5.123) returns "T"
(= (fix (* number1 1000)) 5123) returns "T"

(3) 5.1234
If (setq number1 (getreal "\n\nInput A Real: ")) and 5.1234 was entered, or simply set (setq number1 5.1234)
(= number1 5.1234) always returns "T"
(= (fix (* number1 10000)) 51234) always returns "T"
Title: Re: A Bug or Not A Bug
Post by: Keith™ on August 02, 2017, 09:21:00 PM
I cannot verity that problem using 2014 or 2017.
Perhaps you can verify the value of number1 independently of =

That being said, as others have suggested, equal is probably the best solution until/unless you can confirm it is indeed a bug.

Have you tried this exact scenario on both AMD and Intel processors? I discovered an error on certain Intel processors that was did not exist on AMD processors. It was confirmed independently by the head of the CS department at a local university.
Title: Re: A Bug or Not A Bug
Post by: ronjonp on August 02, 2017, 09:53:24 PM
Definitely some rounding issues:
Code - Auto/Visual Lisp: [Select]
  1. (setq n 5.123)
  2. (rtos (* n 1000) 2 16)
  3. (= 5123 (* n 1000))
  4. (equal 5123 (* n 1000) 1e-8)
  5.  
  6.  
  7. (rtos (* n 1000) 2 16)
  8. (= 5123 (* n 1000))
  9. (equal 5123 (* n 1000) 1e-8)
  10.  
  11.  
  12. ;;;_$
  13. ;;;
  14. ;;;5.123
  15. ;;;"5123.000000000001"
  16. ;;;T
  17. ;;;T
  18. ;;;5.123
  19. ;;;"5122.999999999999"
  20. ;;;nil
  21. ;;;T
  22. ;;;; 8 forms loaded from #<editor "<Untitled-6> loading...">
  23. ;;;_$
Use equal and fuzz as mentioned above .. FWIW when comparing numbers I always use a fuzz factor that is acceptable to me.
Title: Re: A Bug or Not A Bug
Post by: MeasureUp on August 03, 2017, 12:36:25 AM
Hi Keith, thanks for the info.
I didn't know that an Intel/AMD processor could cause this kind of error.
Unfortunately, I cannot test it as all my pc and all the machines at my workplace are with Intel CPU.
Title: Re: A Bug or Not A Bug
Post by: roy_043 on August 03, 2017, 04:56:26 AM
FWIW: My tests were done on the same machine. Maybe getreal can return a 32 bit real (depending on OS or CAD program versions)?
Title: Re: A Bug or Not A Bug
Post by: MeasureUp on August 03, 2017, 08:26:28 PM
Thanks Roy.
Our machines are all 64 bit OS with 64 bit AutoCAD mech 2016.
Sorry I have no chance to test the difference.

BTW it seems not much I can do because IT guys do not want to install 2017 or 2018 versions, even our company has paid for the subscription.
Title: Re: A Bug or Not A Bug
Post by: ronjonp on August 03, 2017, 11:59:32 PM
I'm running 2018 x64 and the rounding issue was there too.
Title: Re: A Bug or Not A Bug
Post by: MeasureUp on August 06, 2017, 07:03:29 PM
Based on everyone's replies, I believe there is a bug with "getreal" function. (well, believe but not 100% sure) => this may be stated as (/= (getreal "100") 100.000%) :-D
In my other thread Lee points out that "rtos" is dependent upon the "dimzin" system variable.
Maybe Lee or someone else can find out a workaround for "getreal"?

BTW for my practice, I will do something like this:
(setq number1 (getreal "\n\nInput A Real: "))
; then redefine "number1"
(setq number1 (princ number1))

Then (= number1 5.123) returns "T".
Title: Re: A Bug or Not A Bug
Post by: VovKa on August 06, 2017, 07:28:47 PM
I believe there is a bug with "getreal" function.
not only getreal but all get* functions

i suspect that autodesk guys decided that get* functions and read/atof should use different techniques the parse the string
just to make life more fun :)
Title: Re: A Bug or Not A Bug
Post by: ronjonp on August 06, 2017, 11:41:44 PM
There are bugs er where .. fuzz value 😋
Title: Re: A Bug or Not A Bug
Post by: Lee Mac on August 07, 2017, 01:02:40 PM
Personally, I don't see that this is a problem. When working with doubles, it is known that rounding can occur at the nth decimal place as any non-integer value is expressed to a limited precision, therefore, providing that you always include a small tolerance when comparing doubles, this issue is not relevant.

My 2p.

Lee
Title: Re: A Bug or Not A Bug
Post by: MeasureUp on August 07, 2017, 08:09:40 PM
I believe there is a bug with "getreal" function.
not only getreal but all get* functions

i suspect that autodesk guys decided that get* functions and read/atof should use different techniques the parse the string
just to make life more fun :)
Thanks for your reply. You opened another window for me. I never thought other get* functions have issues.

And thanks to Lee.

I may put aside this question/problem for now as I still suspect it would be a bug.
Again, I agree that a fuzz obviously gets rid of it but...

Thanks again for everyone's input - they are valuable.