GNU bug report logs - #75105
(cl-random -1.0e+INF)

Previous Next

Package: emacs;

Reported by: Pip Cet <pipcet <at> protonmail.com>

Date: Wed, 25 Dec 2024 23:28:02 UTC

Severity: wishlist

To reply to this bug, email your comments to 75105 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Wed, 25 Dec 2024 23:28:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Pip Cet <pipcet <at> protonmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Wed, 25 Dec 2024 23:28:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> protonmail.com>
To: bug-gnu-emacs <at> gnu.org,
 Mattias Engdegård <mattiasengdegard <at> gmail.com>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: (cl-random -1.0e+INF)
Date: Wed, 25 Dec 2024 23:27:09 +0000
The current behavior of (cl-random -1.0e+INF) is to return NaN with a
probability of 1.1920928955078125e-07, and -1.0e+INF in the remaining
cases.

There are at least two reasonable things cl-random can return for a
negative argument.  cl-random implements both, returning a float with
negative sign or a nonnegative integer.

There are at least two reasonable things cl-random can do in response to
a zero argument.  cl-random implements three of them:

(cl-random 0.0) is 0.0
(cl-random -0.0) is -0.0
(cl-random 0) throws an error

While "(while (not (isnan (cl-random -1.0e+INF))))" is an interesting
benchmark, its behavior may be somewhat surprising.

As this behavior has been in place since at least 1993 (when the
function was called random*), users may rely on it, and only the
docstring should be changed.





Severity set to 'wishlist' from 'normal' Request was from Stefan Kangas <stefankangas <at> gmail.com> to control <at> debbugs.gnu.org. (Thu, 02 Jan 2025 01:25:03 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Sun, 16 Feb 2025 00:51:02 GMT) Full text and rfc822 format available.

Message #10 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> protonmail.com>
To: bug-gnu-emacs <at> gnu.org, 75105 <at> debbugs.gnu.org, mattiasengdegard <at> gmail.com,
 monnier <at> iro.umontreal.ca
Subject: Re: bug#75105: (cl-random -1.0e+INF)
Date: Sun, 16 Feb 2025 00:50:04 +0000
"Pip Cet via \"Bug reports for GNU Emacs, the Swiss army knife of text editors\"" <bug-gnu-emacs <at> gnu.org> writes:

> The current behavior of (cl-random -1.0e+INF) is to return NaN with a
> probability of 1.1920928955078125e-07, and -1.0e+INF in the remaining
> cases.

Okay, so maybe I was wrong and that should be fixed.  This patch will
make cl-random behave consistently, though one could argue about some
cases:

(cl-random 0) involves a division by zero, as it should
(cl-random 1.0e+INF) returns 1.0e+INF, as it should
(cl-random 0.0) returns 0.0, but one could argue it should throw
(cl-random -0.0) should do the same as (cl-random -0.0) since negative
zero is a myth.

Updating the docstring would be nice, too.

From 22e59a481a7a1c2cbff349af0f6faa2f428981a8 Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet <at> protonmail.com>
Subject: [PATCH] Make cl-random behave consistently for unusual arguments
 (bug#75105)

The old behavior was for (cl-random -1.0e+INF) to return NaN in about
one of eight million calls, and -1.0e+INF otherwise.  Other unusual
arguments were handled inconsistently as well.

* lisp/emacs-lisp/cl-extra.el (cl-random): Handle nonnegative
arguments consistently, error for negative arguments.
* test/lisp/emacs-lisp/cl-extra-tests.el (cl-extra-test-random): New
test.
---
 lisp/emacs-lisp/cl-extra.el            | 20 +++++++++++++-------
 test/lisp/emacs-lisp/cl-extra-tests.el | 10 ++++++++++
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el
index 09470457d93..8c218ff9d7e 100644
--- a/lisp/emacs-lisp/cl-extra.el
+++ b/lisp/emacs-lisp/cl-extra.el
@@ -494,13 +494,19 @@ cl-random
     (let* ((i (cl-callf (lambda (x) (% (1+ x) 55)) (cl--random-state-i state)))
 	   (j (cl-callf (lambda (x) (% (1+ x) 55)) (cl--random-state-j state)))
 	   (n (aset vec i (logand 8388607 (- (aref vec i) (aref vec j))))))
-      (if (integerp lim)
-	  (if (<= lim 512) (% n lim)
-	    (if (> lim 8388607) (setq n (+ (ash n 9) (cl-random 512 state))))
-	    (let ((mask 1023))
-	      (while (< mask (1- lim)) (setq mask (1+ (+ mask mask))))
-	      (if (< (setq n (logand n mask)) lim) n (cl-random lim state))))
-	(* (/ n '8388608e0) lim)))))
+      (cond
+       ((natnump lim)
+	(if (<= lim 512) (% n lim)
+	  (if (> lim 8388607) (setq n (+ (ash n 9) (cl-random 512 state))))
+	  (let ((mask 1023))
+	    (while (< mask (1- lim)) (setq mask (1+ (+ mask mask))))
+	    (if (< (setq n (logand n mask)) lim) n (cl-random lim state)))))
+       ((< 0 lim 1.0e+INF)
+        (* (/ n '8388608e0) lim))
+       ((< lim -0.0)
+        (error "negative limit supplied to cl-random"))
+       (t
+        lim)))))
 
 ;;;###autoload
 (defun cl-make-random-state (&optional state)
diff --git a/test/lisp/emacs-lisp/cl-extra-tests.el b/test/lisp/emacs-lisp/cl-extra-tests.el
index 75533b36f29..d87c0bfec5d 100644
--- a/test/lisp/emacs-lisp/cl-extra-tests.el
+++ b/test/lisp/emacs-lisp/cl-extra-tests.el
@@ -348,4 +348,14 @@ cl-extra-test-tailp
     (should (cl-tailp l l))
     (should (not (cl-tailp '(4 5) l)))))
 
+(ert-deftest cl-extra-test-random ()
+  (should-error (cl-random -1))
+  (should-error (cl-random -0.5))
+  (should-error (cl-random -1.0e+INF))
+  (should-error (cl-random 0))
+  (should (eql (cl-random 1) 0)))
+  (should (eql (cl-random 0.0) 0.0))
+  (should (= (cl-random -0.0) 0.0))
+  (should (= (cl-random 1.0e+INF) 1.0e+INF))
+
 ;;; cl-extra-tests.el ends here
-- 
2.48.1





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Sun, 16 Feb 2025 00:51:03 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Mon, 17 Feb 2025 18:10:04 GMT) Full text and rfc822 format available.

Message #16 received at 75105 <at> debbugs.gnu.org (full text, mbox):

From: Mattias Engdegård <mattias.engdegard <at> gmail.com>
To: Pip Cet <pipcet <at> protonmail.com>
Cc: bug-gnu-emacs <at> gnu.org, 75105 <at> debbugs.gnu.org, monnier <at> iro.umontreal.ca,
 mattiasengdegard <at> gmail.com
Subject: Re: bug#75105: (cl-random -1.0e+INF)
Date: Mon, 17 Feb 2025 19:09:51 +0100
16 feb. 2025 kl. 01.50 skrev Pip Cet <pipcet <at> protonmail.com>:

> (cl-random 0.0) returns 0.0, but one could argue it should throw

It definitely should throw, but perhaps it's not worth the incompatibility? Not sure, because existing code that passes 0.0 is likely buggy anyway.
Or we could say that it's just an ad-hoc extension, by vague analogy of (car nil) = nil.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Mon, 17 Feb 2025 18:11:01 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Mon, 17 Feb 2025 18:27:02 GMT) Full text and rfc822 format available.

Message #22 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> protonmail.com>
To: Mattias Engdegård <mattias.engdegard <at> gmail.com>
Cc: bug-gnu-emacs <at> gnu.org, 75105 <at> debbugs.gnu.org, monnier <at> iro.umontreal.ca,
 mattiasengdegard <at> gmail.com
Subject: Re: bug#75105: (cl-random -1.0e+INF)
Date: Mon, 17 Feb 2025 18:26:23 +0000
Mattias Engdegård <mattias.engdegard <at> gmail.com> writes:

> 16 feb. 2025 kl. 01.50 skrev Pip Cet <pipcet <at> protonmail.com>:
>
>> (cl-random 0.0) returns 0.0, but one could argue it should throw
>
> It definitely should throw, but perhaps it's not worth the
> incompatibility? Not sure, because existing code that passes 0.0 is
> likely buggy anyway.  Or we could say that it's just an ad-hoc
> extension, by vague analogy of (car nil) = nil.

On mathematical grounds, in my humble but correct opinion, the
pseudo-algorithm should be:

1. find a random real number in the closed interval [0, a]
2. round it towards zero.

IOW, that 'a' is never the result is a consequence of the rounding step,
not of using a half-open interval in step 1.

However, Common Lisp disagrees, and the cl- prefix kind of hints we
should heed its opinions.

And using (* x (cl-random 1.0)) if that's what you want seems easy
enough (and, either way, you get bitten by the low precision, with only
8 million possible outcomes).

Will modify the patch accordingly.

Pip





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Mon, 17 Feb 2025 18:27:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Mon, 17 Feb 2025 22:18:02 GMT) Full text and rfc822 format available.

Message #28 received at 75105 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Kangas <stefankangas <at> gmail.com>
To: Mattias Engdegård <mattias.engdegard <at> gmail.com>, 
 Pip Cet <pipcet <at> protonmail.com>
Cc: 75105 <at> debbugs.gnu.org, monnier <at> iro.umontreal.ca, mattiasengdegard <at> gmail.com
Subject: Re: bug#75105: (cl-random -1.0e+INF)
Date: Mon, 17 Feb 2025 22:17:34 +0000
Mattias Engdegård <mattias.engdegard <at> gmail.com> writes:

> 16 feb. 2025 kl. 01.50 skrev Pip Cet <pipcet <at> protonmail.com>:
>
>> (cl-random 0.0) returns 0.0, but one could argue it should throw
>
> It definitely should throw, but perhaps it's not worth the incompatibility? Not sure, because existing code that passes 0.0 is likely buggy anyway.
> Or we could say that it's just an ad-hoc extension, by vague analogy of (car nil) = nil.

FWIW, I'd lean towards fixing it, in the hope that very few packages out
there will rely on this wrong behavior.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Mon, 17 Feb 2025 22:25:01 GMT) Full text and rfc822 format available.

Message #31 received at 75105 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> protonmail.com>
To: Stefan Kangas <stefankangas <at> gmail.com>
Cc: Mattias Engdegård <mattias.engdegard <at> gmail.com>,
 75105 <at> debbugs.gnu.org, monnier <at> iro.umontreal.ca, mattiasengdegard <at> gmail.com
Subject: Re: bug#75105: (cl-random -1.0e+INF)
Date: Mon, 17 Feb 2025 22:24:22 +0000
"Stefan Kangas" <stefankangas <at> gmail.com> writes:

> Mattias Engdegård <mattias.engdegard <at> gmail.com> writes:
>
>> 16 feb. 2025 kl. 01.50 skrev Pip Cet <pipcet <at> protonmail.com>:
>>
>>> (cl-random 0.0) returns 0.0, but one could argue it should throw
>>
>> It definitely should throw, but perhaps it's not worth the incompatibility? Not sure, because existing code that passes 0.0 is likely buggy anyway.
>> Or we could say that it's just an ad-hoc extension, by vague analogy of (car nil) = nil.
>
> FWIW, I'd lean towards fixing it, in the hope that very few packages out
> there will rely on this wrong behavior.

Just to clarify, you think (cl-random 0.0) returning 0.0 is wrong
behavior?  If so, everyone agrees we should make it throw, if for
different reasons (I think the 0.0 return value is mathematically
correct but not important enough for us to deviate from the standard, so
I changed my mind after reading that).

Pip





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Mon, 17 Feb 2025 23:15:02 GMT) Full text and rfc822 format available.

Message #34 received at 75105 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Kangas <stefankangas <at> gmail.com>
To: Pip Cet <pipcet <at> protonmail.com>
Cc: Mattias Engdegård <mattias.engdegard <at> gmail.com>,
 75105 <at> debbugs.gnu.org, monnier <at> iro.umontreal.ca, mattiasengdegard <at> gmail.com
Subject: Re: bug#75105: (cl-random -1.0e+INF)
Date: Mon, 17 Feb 2025 15:14:24 -0800
Pip Cet <pipcet <at> protonmail.com> writes:

> "Stefan Kangas" <stefankangas <at> gmail.com> writes:
>
>> Mattias Engdegård <mattias.engdegard <at> gmail.com> writes:
>>
>>> 16 feb. 2025 kl. 01.50 skrev Pip Cet <pipcet <at> protonmail.com>:
>>>
>>>> (cl-random 0.0) returns 0.0, but one could argue it should throw
>>>
>>> It definitely should throw, but perhaps it's not worth the incompatibility? Not sure, because existing code that passes 0.0 is likely buggy anyway.
>>> Or we could say that it's just an ad-hoc extension, by vague analogy of (car nil) = nil.
>>
>> FWIW, I'd lean towards fixing it, in the hope that very few packages out
>> there will rely on this wrong behavior.
>
> Just to clarify, you think (cl-random 0.0) returning 0.0 is wrong
> behavior?

Yes, sorry for not being more clear.

> If so, everyone agrees we should make it throw, if for
> different reasons (I think the 0.0 return value is mathematically
> correct but not important enough for us to deviate from the standard, so
> I changed my mind after reading that).

Right.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Tue, 18 Feb 2025 12:44:02 GMT) Full text and rfc822 format available.

Message #37 received at 75105 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stefan Kangas <stefankangas <at> gmail.com>
Cc: mattias.engdegard <at> gmail.com, 75105 <at> debbugs.gnu.org,
 mattiasengdegard <at> gmail.com, pipcet <at> protonmail.com, monnier <at> iro.umontreal.ca
Subject: Re: bug#75105: (cl-random -1.0e+INF)
Date: Tue, 18 Feb 2025 14:43:32 +0200
> Cc: 75105 <at> debbugs.gnu.org, monnier <at> iro.umontreal.ca, mattiasengdegard <at> gmail.com
> From: Stefan Kangas <stefankangas <at> gmail.com>
> Date: Mon, 17 Feb 2025 22:17:34 +0000
> 
> Mattias Engdegård <mattias.engdegard <at> gmail.com> writes:
> 
> > 16 feb. 2025 kl. 01.50 skrev Pip Cet <pipcet <at> protonmail.com>:
> >
> >> (cl-random 0.0) returns 0.0, but one could argue it should throw
> >
> > It definitely should throw, but perhaps it's not worth the incompatibility? Not sure, because existing code that passes 0.0 is likely buggy anyway.
> > Or we could say that it's just an ad-hoc extension, by vague analogy of (car nil) = nil.

IMO, signaling an error is only justified if the call (cl-random 0.0)
cannot keep the contract of the function according to its doc string.
I don't think the value 0.0 it returns breaks the contract.

> FWIW, I'd lean towards fixing it, in the hope that very few packages out
> there will rely on this wrong behavior.

Fix it how?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Tue, 18 Feb 2025 12:46:02 GMT) Full text and rfc822 format available.

Message #40 received at 75105 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Pip Cet <pipcet <at> protonmail.com>
Cc: mattias.engdegard <at> gmail.com, 75105 <at> debbugs.gnu.org,
 mattiasengdegard <at> gmail.com, stefankangas <at> gmail.com, monnier <at> iro.umontreal.ca
Subject: Re: bug#75105: (cl-random -1.0e+INF)
Date: Tue, 18 Feb 2025 14:45:24 +0200
> Cc: Mattias Engdegård <mattias.engdegard <at> gmail.com>,
>  75105 <at> debbugs.gnu.org, monnier <at> iro.umontreal.ca, mattiasengdegard <at> gmail.com
> Date: Mon, 17 Feb 2025 22:24:22 +0000
> From:  Pip Cet via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
> 
> "Stefan Kangas" <stefankangas <at> gmail.com> writes:
> 
> > Mattias Engdegård <mattias.engdegard <at> gmail.com> writes:
> >
> >> 16 feb. 2025 kl. 01.50 skrev Pip Cet <pipcet <at> protonmail.com>:
> >>
> >>> (cl-random 0.0) returns 0.0, but one could argue it should throw
> >>
> >> It definitely should throw, but perhaps it's not worth the incompatibility? Not sure, because existing code that passes 0.0 is likely buggy anyway.
> >> Or we could say that it's just an ad-hoc extension, by vague analogy of (car nil) = nil.
> >
> > FWIW, I'd lean towards fixing it, in the hope that very few packages out
> > there will rely on this wrong behavior.
> 
> Just to clarify, you think (cl-random 0.0) returning 0.0 is wrong
> behavior?

I don't.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Tue, 18 Feb 2025 12:52:02 GMT) Full text and rfc822 format available.

Message #43 received at 75105 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> protonmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: mattias.engdegard <at> gmail.com, 75105 <at> debbugs.gnu.org,
 mattiasengdegard <at> gmail.com, Stefan Kangas <stefankangas <at> gmail.com>,
 monnier <at> iro.umontreal.ca
Subject: Re: bug#75105: (cl-random -1.0e+INF)
Date: Tue, 18 Feb 2025 12:51:45 +0000
"Eli Zaretskii" <eliz <at> gnu.org> writes:

>> Cc: 75105 <at> debbugs.gnu.org, monnier <at> iro.umontreal.ca, mattiasengdegard <at> gmail.com
>> From: Stefan Kangas <stefankangas <at> gmail.com>
>> Date: Mon, 17 Feb 2025 22:17:34 +0000
>>
>> Mattias Engdegård <mattias.engdegard <at> gmail.com> writes:
>>
>> > 16 feb. 2025 kl. 01.50 skrev Pip Cet <pipcet <at> protonmail.com>:
>> >
>> >> (cl-random 0.0) returns 0.0, but one could argue it should throw
>> >
>> > It definitely should throw, but perhaps it's not worth the incompatibility? Not sure, because existing code that passes 0.0 is likely buggy anyway.
>> > Or we could say that it's just an ad-hoc extension, by vague analogy of (car nil) = nil.
>
> IMO, signaling an error is only justified if the call (cl-random 0.0)
> cannot keep the contract of the function according to its doc string.
> I don't think the value 0.0 it returns breaks the contract.

  "Return a pseudo-random nonnegative number less than LIM, an integer or float.
Optional second arg STATE is a random-state object."

How is 0.0 a "nonnegative number less than 0.0"?  0.0 isn't less than
0.0.

While most users will expect (cl-random 0.0) to return 0.0, which is the
mathematically sensible thing to do for "a random number between 0.0 and
0.0, rounded down", that's not what the docstring currently describes.

We'll just have to hope that no one "optimizes" (* x (cl-random 1.0)) to
(cl-random x) and breaks existing code.

Pip





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Tue, 18 Feb 2025 13:06:02 GMT) Full text and rfc822 format available.

Message #46 received at 75105 <at> debbugs.gnu.org (full text, mbox):

From: Pip Cet <pipcet <at> protonmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: mattias.engdegard <at> gmail.com, 75105 <at> debbugs.gnu.org,
 mattiasengdegard <at> gmail.com, Stefan Kangas <stefankangas <at> gmail.com>,
 monnier <at> iro.umontreal.ca
Subject: Re: bug#75105: (cl-random -1.0e+INF)
Date: Tue, 18 Feb 2025 13:05:03 +0000
Pip Cet <pipcet <at> protonmail.com> writes:

> "Eli Zaretskii" <eliz <at> gnu.org> writes:
>
>>> Cc: 75105 <at> debbugs.gnu.org, monnier <at> iro.umontreal.ca, mattiasengdegard <at> gmail.com
>>> From: Stefan Kangas <stefankangas <at> gmail.com>
>>> Date: Mon, 17 Feb 2025 22:17:34 +0000
>>>
>>> Mattias Engdegård <mattias.engdegard <at> gmail.com> writes:
>>>
>>> > 16 feb. 2025 kl. 01.50 skrev Pip Cet <pipcet <at> protonmail.com>:
>>> >
>>> >> (cl-random 0.0) returns 0.0, but one could argue it should throw
>>> >
>>> > It definitely should throw, but perhaps it's not worth the incompatibility? Not sure, because existing code that passes 0.0 is likely buggy anyway.
>>> > Or we could say that it's just an ad-hoc extension, by vague analogy of (car nil) = nil.
>>
>> IMO, signaling an error is only justified if the call (cl-random 0.0)
>> cannot keep the contract of the function according to its doc string.
>> I don't think the value 0.0 it returns breaks the contract.
>
>   "Return a pseudo-random nonnegative number less than LIM, an integer or float.
> Optional second arg STATE is a random-state object."
>
> How is 0.0 a "nonnegative number less than 0.0"?  0.0 isn't less than
> 0.0.
>
> While most users will expect (cl-random 0.0) to return 0.0, which is the
> mathematically sensible thing to do for "a random number between 0.0 and
> 0.0, rounded down", that's not what the docstring currently describes.
>
> We'll just have to hope that no one "optimizes" (* x (cl-random 1.0)) to
> (cl-random x) and breaks existing code.
>
> Pip

Okay for master?

From de403aa6aaf7525d8523fe620374bcc955cd4b79 Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet <at> protonmail.com>
Subject: [PATCH] Make cl-random behave consistently for unusual arguments
 (bug#75105)

The old behavior was for (cl-random -1.0e+INF) to return NaN in about
one of eight million calls, and -1.0e+INF otherwise.  Other unusual
arguments were handled inconsistently as well.

* lisp/emacs-lisp/cl-extra.el (cl-random): Handle positive finite
arguments consistently, error for nonpositive or infinite arguments.
* test/lisp/emacs-lisp/cl-extra-tests.el (cl-extra-test-random): New
test.
---
 lisp/emacs-lisp/cl-extra.el            | 18 +++++++++++-------
 test/lisp/emacs-lisp/cl-extra-tests.el | 10 ++++++++++
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el
index ab06682cf93..32b9dfd1aa0 100644
--- a/lisp/emacs-lisp/cl-extra.el
+++ b/lisp/emacs-lisp/cl-extra.el
@@ -494,13 +494,17 @@ cl-random
     (let* ((i (cl-callf (lambda (x) (% (1+ x) 55)) (cl--random-state-i state)))
 	   (j (cl-callf (lambda (x) (% (1+ x) 55)) (cl--random-state-j state)))
 	   (n (aset vec i (logand 8388607 (- (aref vec i) (aref vec j))))))
-      (if (integerp lim)
-	  (if (<= lim 512) (% n lim)
-	    (if (> lim 8388607) (setq n (+ (ash n 9) (cl-random 512 state))))
-	    (let ((mask 1023))
-	      (while (< mask (1- lim)) (setq mask (1+ (+ mask mask))))
-	      (if (< (setq n (logand n mask)) lim) n (cl-random lim state))))
-	(* (/ n '8388608e0) lim)))))
+      (cond
+       ((natnump lim)
+	(if (<= lim 512) (% n lim)
+	  (if (> lim 8388607) (setq n (+ (ash n 9) (cl-random 512 state))))
+	  (let ((mask 1023))
+	    (while (< mask (1- lim)) (setq mask (1+ (+ mask mask))))
+	    (if (< (setq n (logand n mask)) lim) n (cl-random lim state)))))
+       ((< 0 lim 1.0e+INF)
+        (* (/ n '8388608e0) lim))
+       (t
+        (error "Limit %S not supported by cl-random" lim))))))
 
 ;;;###autoload
 (defun cl-make-random-state (&optional state)
diff --git a/test/lisp/emacs-lisp/cl-extra-tests.el b/test/lisp/emacs-lisp/cl-extra-tests.el
index c524f77f2bb..1ca661cdc07 100644
--- a/test/lisp/emacs-lisp/cl-extra-tests.el
+++ b/test/lisp/emacs-lisp/cl-extra-tests.el
@@ -348,4 +348,14 @@ cl-extra-test-tailp
     (should (cl-tailp l l))
     (should (not (cl-tailp '(4 5) l)))))
 
+(ert-deftest cl-extra-test-random ()
+  (should-error (cl-random -1))
+  (should-error (cl-random -0.5))
+  (should-error (cl-random -1.0e+INF))
+  (should-error (cl-random 0))
+  (should-error (cl-random 0.0))
+  (should-error (cl-random -0.0))
+  (should-error (cl-random 1.0e+INF))
+  (should (eql (cl-random 1) 0)))
+
 ;;; cl-extra-tests.el ends here
-- 
2.48.1





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Tue, 18 Feb 2025 15:28:02 GMT) Full text and rfc822 format available.

Message #49 received at 75105 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Pip Cet <pipcet <at> protonmail.com>
Cc: mattias.engdegard <at> gmail.com, 75105 <at> debbugs.gnu.org, stefankangas <at> gmail.com,
 monnier <at> iro.umontreal.ca
Subject: Re: bug#75105: (cl-random -1.0e+INF)
Date: Tue, 18 Feb 2025 17:26:49 +0200
> Date: Tue, 18 Feb 2025 12:51:45 +0000
> From: Pip Cet <pipcet <at> protonmail.com>
> Cc: Stefan Kangas <stefankangas <at> gmail.com>, mattias.engdegard <at> gmail.com, 75105 <at> debbugs.gnu.org, monnier <at> iro.umontreal.ca, mattiasengdegard <at> gmail.com
> 
> "Eli Zaretskii" <eliz <at> gnu.org> writes:
> 
> >> Cc: 75105 <at> debbugs.gnu.org, monnier <at> iro.umontreal.ca, mattiasengdegard <at> gmail.com
> >> From: Stefan Kangas <stefankangas <at> gmail.com>
> >> Date: Mon, 17 Feb 2025 22:17:34 +0000
> >>
> >> Mattias Engdegård <mattias.engdegard <at> gmail.com> writes:
> >>
> >> > 16 feb. 2025 kl. 01.50 skrev Pip Cet <pipcet <at> protonmail.com>:
> >> >
> >> >> (cl-random 0.0) returns 0.0, but one could argue it should throw
> >> >
> >> > It definitely should throw, but perhaps it's not worth the incompatibility? Not sure, because existing code that passes 0.0 is likely buggy anyway.
> >> > Or we could say that it's just an ad-hoc extension, by vague analogy of (car nil) = nil.
> >
> > IMO, signaling an error is only justified if the call (cl-random 0.0)
> > cannot keep the contract of the function according to its doc string.
> > I don't think the value 0.0 it returns breaks the contract.
> 
>   "Return a pseudo-random nonnegative number less than LIM, an integer or float.
> Optional second arg STATE is a random-state object."
> 
> How is 0.0 a "nonnegative number less than 0.0"?  0.0 isn't less than
> 0.0.
> 
> While most users will expect (cl-random 0.0) to return 0.0, which is the
> mathematically sensible thing to do for "a random number between 0.0 and
> 0.0, rounded down", that's not what the docstring currently describes.

If the problem is with the doc string, a fix should be easy.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#75105; Package emacs. (Wed, 19 Feb 2025 15:34:02 GMT) Full text and rfc822 format available.

Message #52 received at 75105 <at> debbugs.gnu.org (full text, mbox):

From: Mattias Engdegård <mattias.engdegard <at> gmail.com>
To: Pip Cet <pipcet <at> protonmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 75105 <at> debbugs.gnu.org,
 Stefan Kangas <stefankangas <at> gmail.com>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#75105: (cl-random -1.0e+INF)
Date: Wed, 19 Feb 2025 16:33:21 +0100
18 feb. 2025 kl. 14.05 skrev Pip Cet <pipcet <at> protonmail.com>:

> Okay for master?

Looks fine.





This bug report was last modified 116 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.