Subject: Re: bug#40744: guile-2.2.4 (integer-length 0) erroneously returns 0, not 1

From: Bengt Richter <[email-masked]>
Date: Sat, 24 Jul 2021 19:12:08 +0200

Oops, forgot to reply-all -- sorry about the dup, Rob ;/

On +2021-07-15 22:01:32 -0500, Rob Browning wrote:
> 
> Hmm, the zero result appears to be intentional, i.e. it's mentioned in
> the examples here:
> 
>   https://www.gnu.org/software/guile/manual/guile.html#Arithmetic
> 
> and is also specified by Chez Scheme and SRFI-60:
> 
>   https://www.scheme.com/csug8/numeric.html
>   https://srfi.schemers.org/srfi-60/srfi-60.html
> 
> -- 
> Rob Browning
> rlb @defaultvalue.org and @debian.org
> GPG as of 2011-07-10 E6A9 DA3C C9FD 1FF8 C676 D2C4 C0F0 39E9 ED1B 597A
> GPG as of 2002-11-03 14DD 432F AE39 534D B592 F9A0 25C8 D377 8C7E 73A4

I tried to make a pitch for (integer-length 0) =-> 1 in
[1]    https://lists.gnu.org/archive/html/bug-guile/2020-04/msg00027.html
though I now think integer-length is a useful measure of mathematical
integervalues that can be generalized to any rational numbers and
complex numbers with rational real and imaginary parts.

Also their printed representations can have any rational radix other
than 1 and negative generalized integer-lengths can be meaningful for
length of 1/x vs x (which brings in the zero issue).

For the "integer-length" I compute in [1], I would now suggest an alternate
name: integer-digits -- the number of concrete digit-value representations
it take to represent the polynomial coefficient values in the mathematical
polynomial series.

I should update [1] to reflect what I am saying here to remove complaints
about integer-length 0 etc and talk about integer-digits (or maybe
rational-digits or even numeric-digits?)

I think scheme's integer-length basically solves for minimum L in
in a mapping of rational numbers (limited to integers in its case)
for + and minus like
[0..2**L) for positive and [-2**L..0) for negative.

Those half-open sets correspond, so we can just use the absolute value
like abslen here:
--8<---------------cut here---------------start------------->8---
#!/usr/bin/env -S guile --no-auto-compile -e main -s
!#
(use-modules (ice-9 format))

(define (abslen absint)
  (begin
    (let*((absval absint)
    	  (lm (lambda (aval)
    		(begin
    		  (let inner ((n 0) (av aval))
    		    (begin
    	              (if
    	               (< (integer-expt 2 n) av) 
    	               (inner (+ 1 n) av)
    	               n)))))))
	(lm absval))))

(define (main args)
  (begin
    (or
     (false-if-exception 
      (begin
	(display (abslen (abs (string->number (cadr args)))))
	(newline)))
     (begin
       (format #t "\nUsage: ~a NUM -- where NUM is [+ - ] POSITIVE_INTEGER\n" (car args)))
     (newline))))
--8<---------------cut here---------------end--------------->8---

You might want to call the above something other than integer-length,
but it should compute the same result (modulo very limited testing :).

As mentioned in Tom's reply to [1], zero makes for a special problem
in the general mathematical case, where I think you have to special-case
which set of points it should belong to.

In the general case numbers map into half-open annuli in the complex plane,
where inside and outside the unit circle corresponds to x and 1/x, and 1/0
has to be special-cased. The annulus edge circles are at powers of a rational
base, 2 in the binary case, but 4/3 can work. Just not irrationals.
(Maybe as named unit values though?)

Conventional signed number mappings split an annulus in two to map them,
with positives < the splitting circle and negatives >=

Something analogous to abslen can be done to find the power of the base
that will be the diameter of a circle containing (> not >=) both parts
of the split annulus. I haven't done it yet :)

Complex numbers have both cartesian and polar representations, so that
brings in interesting stuff too. The negative of a complex number as
a point in the complex plane is diametrically opposite the origin, but
zero has no direction to an opposite of itself :)
Defining -0 to be 0 has consequences. (Note that fp hardware does
represent -0 :)

You might find it amusing to play with the scheme program
included in [1] (after you inspect it -- no warranties :).

-- 
Regards,
Bengt Richter
PS. Shouldn't euclidean-quotient always produce an exact integer?
(Inexactness if any can be carried by the remainder)