From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Mark H Weaver Newsgroups: gmane.lisp.guile.bugs Subject: bug#30426: division inconsistency? Date: Mon, 12 Feb 2018 16:01:39 -0500 Message-ID: <874lmlrkgc.fsf@netris.org> References: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1518469293 16609 195.159.176.226 (12 Feb 2018 21:01:33 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 12 Feb 2018 21:01:33 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) Cc: 30426@debbugs.gnu.org To: bil@ccrma.Stanford.EDU Original-X-From: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Mon Feb 12 22:01:29 2018 Return-path: Envelope-to: guile-bugs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1elLDs-0002to-CN for guile-bugs@m.gmane.org; Mon, 12 Feb 2018 22:01:12 +0100 Original-Received: from localhost ([::1]:52866 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1elLFs-0001yp-H3 for guile-bugs@m.gmane.org; Mon, 12 Feb 2018 16:03:16 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:43292) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1elLFi-0001xJ-85 for bug-guile@gnu.org; Mon, 12 Feb 2018 16:03:08 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1elLFe-0000OZ-VE for bug-guile@gnu.org; Mon, 12 Feb 2018 16:03:06 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:60434) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1elLFe-0000O1-PE for bug-guile@gnu.org; Mon, 12 Feb 2018 16:03:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1elLFe-0000eX-Gu for bug-guile@gnu.org; Mon, 12 Feb 2018 16:03:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Mark H Weaver Original-Sender: "Debbugs-submit" Resent-CC: bug-guile@gnu.org Resent-Date: Mon, 12 Feb 2018 21:03:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30426 X-GNU-PR-Package: guile X-GNU-PR-Keywords: Original-Received: via spool by 30426-submit@debbugs.gnu.org id=B30426.15184693412459 (code B ref 30426); Mon, 12 Feb 2018 21:03:02 +0000 Original-Received: (at 30426) by debbugs.gnu.org; 12 Feb 2018 21:02:21 +0000 Original-Received: from localhost ([127.0.0.1]:40098 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1elLEy-0000db-Qx for submit@debbugs.gnu.org; Mon, 12 Feb 2018 16:02:21 -0500 Original-Received: from world.peace.net ([50.252.239.5]:49992) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1elLEw-0000dN-P2 for 30426@debbugs.gnu.org; Mon, 12 Feb 2018 16:02:19 -0500 Original-Received: from pool-72-93-28-59.bstnma.east.verizon.net ([72.93.28.59] helo=jojen) by world.peace.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1elLEq-0004c1-9I; Mon, 12 Feb 2018 16:02:12 -0500 In-Reply-To: (bil@ccrma.stanford.edu's message of "Sun, 11 Feb 2018 14:56:54 -0800") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-guile@gnu.org List-Id: "Bug reports for GUILE, GNU's Ubiquitous Extension Language" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Original-Sender: "bug-guile" Xref: news.gmane.org gmane.lisp.guile.bugs:9002 Archived-At: Hi, bil@ccrma.Stanford.EDU writes: > scheme@(guile-user)> (help '/) > - Scheme Procedure: / [x [y . rest]] > Divide the first argument by the product of the remaining > arguments. If called with one argument Z1, 1/Z1 is returned. This help text is indeed incorrect. In fact, (/ x y z) is evaluated as (/ (/ x y) z), which is not necessarily the same as (/ x (* y z)) when using inexact arithmetic. > A possible inconsistency: > > scheme@(guile-user)> (version) > $1 = "2.0.13" > > scheme@(guile-user)> (/ 1 (* 0 +nan.0)) > $2 = +nan.0 Many years ago, I concluded that (* 0 +nan.0) and (* 0 +inf.0) should be +nan.0, and that's what Guile does. I now believe that (* 0 ) should be 0. Both of these behaviors are allowed by the R6RS. Note that when I write '0', I mean an _exact_ zero. So, the above expression may raise an exception in a future version of Guile. > scheme@(guile-user)> (/ 1 0 +nan.0) > :3:0: In procedure # input>:3:0 ()>: > :3:0: Throw to key `numerical-overflow' with args `("/" > "Numerical overflow" #f #f) The R6RS specifies that if all arguments to '/' are exact, then the divisors must all be nonzero. That does not apply to the above '/' call because of the inexact +nan.0 argument. However, our compiler transforms (/ x y z) to (/ (/ x y) z) in an early pass. > scheme@(guile-user)> (/ 1 +nan.0 0) > :5:0: In procedure # input>:5:0 ()>: > :5:0: Throw to key `numerical-overflow' with args `("/" > "Numerical overflow" #f #f) This should probably return +nan.0, and that's what happens in Guile 2.2 for compiled code. For some of these edge cases, our compiler has different behavior than our core numeric procedures. Our core '/' operator, as defined in numbers.c, raises an exception for (/ x 0), for any 'x'. This does not conform to the R6RS, which specifies that (/ 0.0 0) => +inf.0. I don't think that rule makes sense because the sign of the result cannot be justified. (/ 1 0.0) => +inf.0 and (/ 1 -0.0) => -inf.0 are more justifiable because of the signed inexact zeroes, but an exact zero is not signed. However, it may be that we should change this to conform to the R6RS, and certainly it would be good for our compiler and interpreter to agree on all of these edge cases. > scheme@(guile-user)> (* +nan.0 0) > $1 = +nan.0 > scheme@(guile-user)> (/ 1 +nan.0) > $2 = +nan.0 > > similarly with +inf.0: > > scheme@(guile-user)> (/ 1 (* +inf.0 0)) > $3 = +nan.0 If we change Guile so that (* 0 x) => 0 for all x, then the expression above will raise an exception in a future version of Guile. > scheme@(guile-user)> (/ 1 +inf.0 0) > :6:0: In procedure # input>:6:0 ()>: > :6:0: Throw to key `numerical-overflow' with args `("/" > "Numerical overflow" #f #f) As with the (/ 1 +nan.0 0) case above, this should probably return +nan.0, and that's what happens in Guile 2.2 for compiled code. What do you think? Regards, Mark