Lisp HUG Maillist Archive

ZEROP broken after DECLARE REAL

DESCRIPTION: ZEROP not working after REAL declaration <and a simple test case, if possible>

This code fails to detect that den is zero:

(defun aitken (a b c)
  (declare (real a b c)) ;; <-- this seems to be the culprit...
  (let* ((den (- (- c b) (- b a)))
         (cnew (if (zerop den)
                   c
                 (- c (/ (* (- c b) (- c b)) den)))))
    cnew))

(aitken 0d0 0d0 0d0) => Error: Division by zero...

But this version works just fine:

(defun aitken (a b c)
  (let* ((den (- (- c b) (- b a)))
         (cnew (if (zerop den)
                   c
                 (- c (/ (* (- c b) (- c b)) den)))))
    cnew))

(aitken 0d0 0d0 0d0) => 0d0


IMPACT: Broken

URGENCY: Next Release



PRODUCT CONFIGURATION:

  LispWorks 7.0.0

Process name: /Applications/LispWorks 7.0 (64-bit)/LispWorks (64-bit).app/Contents/MacOS/lispworks-7-0-0-amd64-darwin
   ID: 13302    Started at: 2017/02/03 18:03:22

Save history:

1: lispworks-7-0-0-0-amd64-darwin-release-base
Saved by davef as lispworks-7-0-0-0-amd64-darwin-release-base, at 26 Nov 2014 20:00

2: lispworks-7-0-0-0-amd64-darwin-release-cocoa-shaken
Saved by davef as lispworks-7-0-0-0-amd64-darwin-release-cocoa-shaken, at 27 Nov 2014 10:07

3: lispworks-7-0-0-0-amd64-darwin-release-cocoa-shaken
Saved by davef as lispworks-7-0-0-amd64-darwin, at 13 Mar 2015 14:30
LispWorks 7.0.0

Loaded Modules:  "NREGEX", "describe", "inspector-values", "CHARSETS",
  "c-arrays", "comm", "SDLE-STORE", "mt-random", "IRONCLAD",
  "dynamic-complete", "ASDF", "asdf", "UIOP", "uiop"

Public patches:  COMM 1.4
Private patches:  COMPILER-MV-AND-CLOSURE,
  CAPI-COCOA-WITH-PORT-CONTEXT-CURRENT, COCOA-NSGLYPHSTORAGE-REMOVED,
  CAPI-LAYOUT-DIVIDER-PERFORM-MOVE, COCOA-NS-ALERTS,
  CAPI-COCOA-PROMPTERS-NON-DEPRECATED

Foreign modules:
  #<FLI::INTERNAL-MODULE :LISP : exports = 0>
  #<FLI::INTERNAL-MODULE :CALLBACKS : exports = 0>
  #<FLI::EXTERNAL-MODULE :CARBON-CORE  {/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/CarbonCore}: handle = #<Pointer: FLI::MACH-HEADER-POINTER = #x00007FFF7EEAD000>; exports = 2>
  #<FLI::EXTERNAL-MODULE :FFTLIB  {/usr/local/lib64/liblispfft.dylib}: handle = #<Pointer: FLI::MACH-HEADER-POINTER = #x00000001000CB000>; exports = 1>
  #<FLI::EXTERNAL-MODULE :SIGLAB  : handle = #x00000000; exports = 0>
  #<FLI::EXTERNAL-MODULE #P"/usr/local/lib64/liblispnrutil.dylib"  : handle = #x00000000; exports = 0>
  #<FLI::EXTERNAL-MODULE #P"/usr/local/lib64/liblispplotterstuff.dylib"  : handle = #x00000000; exports = 0>
  #<FLI::EXTERNAL-MODULE #P"/usr/local/lib64/liblispburg.dylib"  : handle = #x00000000; exports = 0>
  #<FLI::EXTERNAL-MODULE "/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation"  {/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation}: handle = #<Pointer: FLI::MACH-HEADER-POINTER = #x00007FFF7FA0F000>; exports = 0>
  #<FLI::EXTERNAL-MODULE "/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa"  {/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa}: handle = #<Pointer: FLI::MACH-HEADER-POINTER = #x00007FFF7DA28000>; exports = 0>
  #<FLI::EXTERNAL-MODULE :DARWIN-LW-OBJC  {/private/var/tmp/lwtemp_Davids-Mac-mini_133020gmOHU3.dylib}: handle = #<Pointer: FLI::MACH-HEADER-POINTER = #x00000001000F0000>; exports = 0>

Signal Handlers
2       SYSTEM::SIGINT-HANDLER
13      SYSTEM::THE-NULL-FUNCTION
20      SYSTEM::GET-CHILDREN-INF
23      SYSTEM::THE-NULL-FUNCTION
30      MP::CALL-BREAK-OF-MP
31      MP::PANIC

Added features: (:COM.SD :ASDF-UNICODE :NON-BASE-CHARS-EXIST-P :OS-UNIX :OS-MACOSX :ASDF :ASDF2 :ASDF3 :ASDF3.1 :ASDF-PACKAGE-SYSTEM ...)

HOST CONFIGURATION:

  Davids-Mac-mini.local (x86 PENTIUM_3), Darwin 16.4.0

LWSerialNumber: LWENT0700051500141599

Site: Unknown

Backtrace: <please use :BB>

 > Generation 7: 33907696 (0x20563F0)
       Cons               4774352 (0x48D9D0)
       Non-Pointer        3213752 (0x3109B8)
       Other              8048192 (0x7ACE40)
       Symbol             2881680 (0x2BF890)
       Function           14569120 (0xDE4EA0)
       Non-Pointer-Static 5528 (0x1598)
       Mixed-Static       414360 (0x65298)
       Weak               712 (0x2C8)
 -- Segments:
       Cons               40C0038800 - 40C04C9000
       Non-Pointer        40D0000800 - 40D0314000
       Other              40E0038800 - 40E07E8000
       Symbol             40F0038800 - 40F02FB000
       Function           4100038800 - 4100E20000
       Non-Pointer-Static 40B0000800 - 40B000D000
       Mixed-Static       400004E800 - 40000C8000
       Weak               4110038800 - 4110039000
================================
 > Generation 6: 0 (0x0)
 > Generation 5: 0 (0x0)
 > Generation 4: 0 (0x0)
 > Generation 3: 46757992 (0x2C97868)
       Cons               12956752 (0xC5B450)
       Non-Pointer        6122960 (0x5D6DD0)
       Other              19179840 (0x124A940)
       Symbol             1267008 (0x135540)
       Function           7229288 (0x6E4F68)
       Weak               2144 (0x860)
 -- Segments:
       Cons               41F0018800 - 41F1019000
       Non-Pointer        4120000800 - 41213C6000
       Other              41D0018800 - 41D1C5B000
       Symbol             41E0018800 - 41E0914000
       Function           4200018800 - 4200819000
       Weak               4210018800 - 4210059000
================================
 > Generation 2: 9516256 (0x9134E0)
       Cons               555616 (0x87A60)
       Non-Pointer        6422280 (0x61FF08)
       Other              1264928 (0x134D20)
       Function           38928 (0x9810)
       Non-Pointer-Static 1234280 (0x12D568)
       Mixed-Static       64 (0x40)
       Weak               160 (0xA0)
 -- Segments:
       Cons               4230010800 - 4231411000
       Non-Pointer        4240000800 - 4241401000
       Other              4250010800 - 4251011000
       Symbol             4170010800 - 4170811000
       Function           4260010800 - 4260811000
       Non-Pointer-Static 4040000800 - 4040136000
       Mixed-Static       4090010800 - 4090013000
       Weak               4270010800 - 4270051000
================================
 > Generation 1: 5234064 (0x4FDD90)
       Cons               972464 (0xED6B0)
       Non-Pointer        1760136 (0x1ADB88)
       Other              2488848 (0x25FA10)
       Function           12552 (0x3108)
       Weak               64 (0x40)
 -- Segments:
       Cons               4190008800 - 4190869000
       Non-Pointer        41A0000800 - 41A0459000
       Other              41B0008800 - 41B0861000
       Symbol             4070008800 - 4070009000
       Function           41C0008800 - 41C002B000
       Weak               4080008800 - 4080009000
================================
 > Generation 0: 10934960 (0xA6DAB0)
       Cons               3942768 (0x3C2970)
       Non-Pointer        1990240 (0x1E5E60)
       Other              4929240 (0x4B36D8)
       Function           72680 (0x11BE8)
       Weak               32 (0x20)
 -- Segments:
       Cons               4010000800 - 401040B000
       Non-Pointer        4030000800 - 4030470000
       Other              4020000800 - 4020710000
       Symbol             4150000800 - 4150200000
       Function           4060000800 - 4060124000
       Weak               40A0000800 - 40A0041000
================================

Total allocated 106350968 (0x656C978), total size 248369152 (0xECDD000) 

Re: ZEROP broken after DECLARE REAL

> On 4 Feb 2017, at 14:36, David McClain <dbm@refined-audiometrics.com> wrote:
> 
> (defun aitken (a b c)
>   (declare (real a b c)) ;; <-- this seems to be the culprit...
>   (let* ((den (- (- c b) (- b a)))
>          (cnew (if (zerop den)
>                    c
>                  (- c (/ (* (- c b) (- c b)) den)))))
>     cnew))

There are even simpler nasties.  Given this:

(defun tiny (a)
  (declare (real a))
  (let ((d (+ a 0)))
    (values (= d a) 
            (zerop d) (zerop a)
            (= d 0) (= a 0))))

then

CL-USER 33 > (tiny 0.0e0)
t
nil
t
nil
t

Which I think can't be right.  You need to perform some arithmetic operation on the argument and it needs to be a float of some kind I think.  It smells to me like there must be hidden bits which make it not quite zero or something.  I'm using 7.0. but the 32-bit one, on a Mac.

--tim


_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html

Re: ZEROP broken after DECLARE REAL

It is incorrect to compare floating point numbers with zero, read here
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

Tim Bradshaw <tfb@tfeb.org> writes:

>> On 4 Feb 2017, at 14:36, David McClain <dbm@refined-audiometrics.com> wrote:
>> 
>> (defun aitken (a b c)
>>   (declare (real a b c)) ;; <-- this seems to be the culprit...
>>   (let* ((den (- (- c b) (- b a)))
>>          (cnew (if (zerop den)
>>                    c
>>                  (- c (/ (* (- c b) (- c b)) den)))))
>>     cnew))
>
> There are even simpler nasties.  Given this:
>
> (defun tiny (a)
>   (declare (real a))
>   (let ((d (+ a 0)))
>     (values (= d a) 
>             (zerop d) (zerop a)
>             (= d 0) (= a 0))))
>
> then
>
> CL-USER 33 > (tiny 0.0e0)
> t
> nil
> t
> nil
> t
>
> Which I think can't be right.  You need to perform some arithmetic operation on the argument and it needs to be a float of some kind I think.  It smells to me like there must be hidden bits which make it not quite zero or something.  I'm using 7.0. but the 32-bit one, on a Mac.
>
> --tim
>
>
> _______________________________________________
> Lisp Hug - the mailing list for LispWorks users
> lisp-hug@lispworks.com
> http://www.lispworks.com/support/lisp-hug.html

-- 
Br,
/Alexey

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html

Re: ZEROP broken after DECLARE REAL

Ah yes, thanks for mentioning that… It all depends on the FTZ and DAZ bits in control registers too…  (Sorry about the mistaken posting yesterday. It was aimed at Lispworks-support, but wound up here, thanks to auto-complete…)

- DM


> On Feb 5, 2017, at 14:33, Alexey Veretennikov <txm.fourier@gmail.com> wrote:
> 
> It is incorrect to compare floating point numbers with zero, read here
> http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
> 
> Tim Bradshaw <tfb@tfeb.org> writes:
> 
>>> On 4 Feb 2017, at 14:36, David McClain <dbm@refined-audiometrics.com> wrote:
>>> 
>>> (defun aitken (a b c)
>>>  (declare (real a b c)) ;; <-- this seems to be the culprit...
>>>  (let* ((den (- (- c b) (- b a)))
>>>         (cnew (if (zerop den)
>>>                   c
>>>                 (- c (/ (* (- c b) (- c b)) den)))))
>>>    cnew))
>> 
>> There are even simpler nasties.  Given this:
>> 
>> (defun tiny (a)
>>  (declare (real a))
>>  (let ((d (+ a 0)))
>>    (values (= d a) 
>>            (zerop d) (zerop a)
>>            (= d 0) (= a 0))))
>> 
>> then
>> 
>> CL-USER 33 > (tiny 0.0e0)
>> t
>> nil
>> t
>> nil
>> t
>> 
>> Which I think can't be right.  You need to perform some arithmetic operation on the argument and it needs to be a float of some kind I think.  It smells to me like there must be hidden bits which make it not quite zero or something.  I'm using 7.0. but the 32-bit one, on a Mac.
>> 
>> --tim
>> 
>> 
>> _______________________________________________
>> Lisp Hug - the mailing list for LispWorks users
>> lisp-hug@lispworks.com
>> http://www.lispworks.com/support/lisp-hug.html
> 
> -- 
> Br,
> /Alexey
> 
> _______________________________________________
> Lisp Hug - the mailing list for LispWorks users
> lisp-hug@lispworks.com
> http://www.lispworks.com/support/lisp-hug.html
> 


_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html

Re: ZEROP broken after DECLARE REAL

OTOH… what I was looking for was a way to avoid the “Divide by Zero” error. That must be an improper error message too?

- DM


> On Feb 5, 2017, at 15:27, David McClain <dbm@refined-audiometrics.com> wrote:
> 
> Ah yes, thanks for mentioning that… It all depends on the FTZ and DAZ bits in control registers too…  (Sorry about the mistaken posting yesterday. It was aimed at Lispworks-support, but wound up here, thanks to auto-complete…)
> 
> - DM
> 
> 
>> On Feb 5, 2017, at 14:33, Alexey Veretennikov <txm.fourier@gmail.com> wrote:
>> 
>> It is incorrect to compare floating point numbers with zero, read here
>> http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
>> 
>> Tim Bradshaw <tfb@tfeb.org> writes:
>> 
>>>> On 4 Feb 2017, at 14:36, David McClain <dbm@refined-audiometrics.com> wrote:
>>>> 
>>>> (defun aitken (a b c)
>>>> (declare (real a b c)) ;; <-- this seems to be the culprit...
>>>> (let* ((den (- (- c b) (- b a)))
>>>>        (cnew (if (zerop den)
>>>>                  c
>>>>                (- c (/ (* (- c b) (- c b)) den)))))
>>>>   cnew))
>>> 
>>> There are even simpler nasties.  Given this:
>>> 
>>> (defun tiny (a)
>>> (declare (real a))
>>> (let ((d (+ a 0)))
>>>   (values (= d a) 
>>>           (zerop d) (zerop a)
>>>           (= d 0) (= a 0))))
>>> 
>>> then
>>> 
>>> CL-USER 33 > (tiny 0.0e0)
>>> t
>>> nil
>>> t
>>> nil
>>> t
>>> 
>>> Which I think can't be right.  You need to perform some arithmetic operation on the argument and it needs to be a float of some kind I think.  It smells to me like there must be hidden bits which make it not quite zero or something.  I'm using 7.0. but the 32-bit one, on a Mac.
>>> 
>>> --tim
>>> 
>>> 
>>> _______________________________________________
>>> Lisp Hug - the mailing list for LispWorks users
>>> lisp-hug@lispworks.com
>>> http://www.lispworks.com/support/lisp-hug.html
>> 
>> -- 
>> Br,
>> /Alexey
>> 
>> _______________________________________________
>> Lisp Hug - the mailing list for LispWorks users
>> lisp-hug@lispworks.com
>> http://www.lispworks.com/support/lisp-hug.html
>> 
> 


_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html

Re: ZEROP broken after DECLARE REAL

… so I guess what I’m trying to state is,

If I am going to receive the ill-formed “Divide by Zero” error in (/ Y X), then why shouldn’t (ZEROP X) return true?

- DM


> On Feb 5, 2017, at 15:28, David McClain <dbm@refined-audiometrics.com> wrote:
> 
> OTOH… what I was looking for was a way to avoid the “Divide by Zero” error. That must be an improper error message too?
> 
> - DM
> 
> 
>> On Feb 5, 2017, at 15:27, David McClain <dbm@refined-audiometrics.com> wrote:
>> 
>> Ah yes, thanks for mentioning that… It all depends on the FTZ and DAZ bits in control registers too…  (Sorry about the mistaken posting yesterday. It was aimed at Lispworks-support, but wound up here, thanks to auto-complete…)
>> 
>> - DM
>> 
>> 
>>> On Feb 5, 2017, at 14:33, Alexey Veretennikov <txm.fourier@gmail.com> wrote:
>>> 
>>> It is incorrect to compare floating point numbers with zero, read here
>>> http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
>>> 
>>> Tim Bradshaw <tfb@tfeb.org> writes:
>>> 
>>>>> On 4 Feb 2017, at 14:36, David McClain <dbm@refined-audiometrics.com> wrote:
>>>>> 
>>>>> (defun aitken (a b c)
>>>>> (declare (real a b c)) ;; <-- this seems to be the culprit...
>>>>> (let* ((den (- (- c b) (- b a)))
>>>>>       (cnew (if (zerop den)
>>>>>                 c
>>>>>               (- c (/ (* (- c b) (- c b)) den)))))
>>>>>  cnew))
>>>> 
>>>> There are even simpler nasties.  Given this:
>>>> 
>>>> (defun tiny (a)
>>>> (declare (real a))
>>>> (let ((d (+ a 0)))
>>>>  (values (= d a) 
>>>>          (zerop d) (zerop a)
>>>>          (= d 0) (= a 0))))
>>>> 
>>>> then
>>>> 
>>>> CL-USER 33 > (tiny 0.0e0)
>>>> t
>>>> nil
>>>> t
>>>> nil
>>>> t
>>>> 
>>>> Which I think can't be right.  You need to perform some arithmetic operation on the argument and it needs to be a float of some kind I think.  It smells to me like there must be hidden bits which make it not quite zero or something.  I'm using 7.0. but the 32-bit one, on a Mac.
>>>> 
>>>> --tim
>>>> 
>>>> 
>>>> _______________________________________________
>>>> Lisp Hug - the mailing list for LispWorks users
>>>> lisp-hug@lispworks.com
>>>> http://www.lispworks.com/support/lisp-hug.html
>>> 
>>> -- 
>>> Br,
>>> /Alexey
>>> 
>>> _______________________________________________
>>> Lisp Hug - the mailing list for LispWorks users
>>> lisp-hug@lispworks.com
>>> http://www.lispworks.com/support/lisp-hug.html
>>> 
>> 
> 


_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html

Re: ZEROP broken after DECLARE REAL

On 5 Feb 2017, at 21:33, Alexey Veretennikov <txm.fourier@gmail.com> wrote:
> 
> It is incorrect to compare floating point numbers with zero, read here
> http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

My naive understanding is that in practice it's never a good idea to compare floats for equality at all.

But while I haven't read the details of IEEE 754 (or I have, but not for more than 20 years), can it be the case that there are two floats (of the same precision) a and b where a and b compare equal but exactly one of them is zero?  Perhaps it can!

This shows what I mean:

(defun tiny (a)
 (declare (real a))
 (let ((b (+ a 0)))
   (and (= a b)
        (or (and (zerop a) (not (zerop b)))
            (and (zerop b) (not (zerop a)))))))

And I am surprised that (tiny 0.0) returns t.

(Apologies for not realising the message I replied to before was a misdirected bug report & hence causing this noise: I was asleep.)

--tim

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html

Re: ZEROP broken after DECLARE REAL

Unable to parse email body. Email id is 14210

Updated at: 2020-12-10 08:31 UTC