From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Kevin Ryde Newsgroups: gmane.lisp.guile.devel Subject: integer-length on negative bignum Date: Sun, 04 May 2003 09:55:52 +1000 Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Message-ID: <87d6izlh4n.fsf@zip.com.au> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: main.gmane.org 1052006197 3818 80.91.224.249 (3 May 2003 23:56:37 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Sat, 3 May 2003 23:56:37 +0000 (UTC) Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sun May 04 01:56:33 2003 Return-path: Original-Received: from monty-python.gnu.org ([199.232.76.173]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 19C6rp-0000z8-00 for ; Sun, 04 May 2003 01:56:33 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.10.13) id 19C6t1-0006Oa-02 for guile-devel@m.gmane.org; Sat, 03 May 2003 19:57:47 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.10.13) id 19C6s1-0005vx-00 for guile-devel@gnu.org; Sat, 03 May 2003 19:56:45 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.10.13) id 19C6rd-0005cd-00 for guile-devel@gnu.org; Sat, 03 May 2003 19:56:24 -0400 Original-Received: from snoopy.pacific.net.au ([61.8.0.36]) by monty-python.gnu.org with esmtp (Exim 4.10.13) id 19C6rO-0005RT-00 for guile-devel@gnu.org; Sat, 03 May 2003 19:56:06 -0400 Original-Received: from sunny.pacific.net.au (sunny.pacific.net.au [203.2.228.40]) h43Nu1s7031721 for ; Sun, 4 May 2003 09:56:01 +1000 Original-Received: from wisma.pacific.net.au (wisma.pacific.net.au [210.23.129.72]) by sunny.pacific.net.au with ESMTP id h43Nu1Qg002751 for ; Sun, 4 May 2003 09:56:01 +1000 (EST) Original-Received: from localhost (ppp30.dyn228.pacific.net.au [203.143.228.30]) by wisma.pacific.net.au (8.12.9/8.12.9) with ESMTP id h43NtxYZ004356 for ; Sun, 4 May 2003 09:56:00 +1000 (EST) Original-Received: from gg by localhost with local (Exim 3.35 #1 (Debian)) id 19C6rA-00043E-00; Sun, 04 May 2003 09:55:52 +1000 Original-To: guile-devel@gnu.org User-Agent: Gnus/5.090019 (Oort Gnus v0.19) Emacs/21.2 (gnu/linux) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1b5 Precedence: list List-Id: Developers list for Guile, the GNU extensibility library List-Help: List-Post: List-Subscribe: , List-Archive: List-Unsubscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: main.gmane.org gmane.lisp.guile.devel:2255 X-Report-Spam: http://spam.gmane.org/gmane.lisp.guile.devel:2255 --=-=-= A small bug in integer-length, assuming I understand what that function is meant to be doing. This lets it correspond to the inum case at least. * numbers.c (scm_integer_length): On negative bignums, adjust mpz_sizeinbase to account for it looking at absolute value where we want ones-complement. * tests/numbers.test (integer-length): Exercise some negatives, in particular "...11100..00". In the tests here, it's only ...11100..00 which is affected by the problem, the others are already right, I just added them for coverage and confirmation of what integer-length does. --=-=-= Content-Disposition: attachment; filename=numbers.c.integer-length.diff --- numbers.c.~1.181.~ 2003-05-04 09:09:49.000000000 +1000 +++ numbers.c 2003-05-04 09:44:31.000000000 +1000 @@ -1438,7 +1438,14 @@ }; return SCM_MAKINUM (c - 4 + l); } else if (SCM_BIGP (n)) { + /* mpz_sizeinbase looks at the absolute value of negatives, whereas we + want a ones-complement. If n is ...111100..00 then mpz_sizeinbase is + 1 too big, so check for that and adjust. */ size_t size = mpz_sizeinbase (SCM_I_BIG_MPZ (n), 2); + if (mpz_sgn (SCM_I_BIG_MPZ (n)) < 0 + && mpz_scan0 (SCM_I_BIG_MPZ (n), /* no 0 bits above the lowest 1 */ + mpz_scan1 (SCM_I_BIG_MPZ (n), 0)) == ULONG_MAX) + size--; scm_remember_upto_here_1 (n); return SCM_MAKINUM (size); } else { --=-=-= Content-Disposition: attachment; filename=numbers.test.integer-length.diff --- numbers.test.~1.17.~ 2003-05-04 09:11:34.000000000 +1000 +++ numbers.test 2003-05-04 09:41:02.000000000 +1000 @@ -1739,3 +1739,32 @@ ;;; ;;; inexact->exact ;;; + +;;; +;;; integer-length +;;; + +(with-test-prefix "integer-length" + + (with-test-prefix "negatives ...11100..00" + (do ((n -1 (ash n 1)) + (i 0 (1+ i))) + ((> i 256)) + (pass-if (list n "expect" i) + (= i (integer-length n))))) + + (with-test-prefix "negatives ...11100..01" + (do ((n -3 (logxor 3 (ash n 1))) + (i 2 (1+ i))) + ((> i 256)) + (pass-if n + (= i (integer-length n))))) + + (with-test-prefix "negatives ...111011..11" + (do ((n -2 (1+ (ash n 1))) + (i 1 (1+ i))) + ((> i 256)) + (pass-if n + (= i (integer-length n)))))) + + --=-=-= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel --=-=-=--