max-int Bradley Lucier (25 Jan 2024 21:40 UTC)
Re: max-int John Cowan (26 Jan 2024 05:28 UTC)
Re: max-int Bradley Lucier (26 Jan 2024 14:23 UTC)
(missing)
Re: max-int Bradley Lucier (26 Jan 2024 16:30 UTC)
Re: max-int Marc Feeley (26 Jan 2024 17:42 UTC)
Re: max-int John Cowan (26 Jan 2024 22:10 UTC)
Re: max-int Bradley Lucier (27 Jan 2024 01:00 UTC)
Re: max-int Shiro Kawai (27 Jan 2024 08:39 UTC)
Re: max-int Antero Mejr (27 Jan 2024 21:29 UTC)

Re: max-int Marc Feeley 26 Jan 2024 17:42 UTC

While there is no foolproof way to determine the size of fixnums, there are heuristic ways to get this value.  For example see the attached program.

Marc

;; File: determine-max-fixnum.scm

;; This R7RS program determines the size of fixnums heuristically. It
;; uses the ephemeron library (SRFI 124) to count how many garbage
;; collections occur during a loop that computes (+ x 1). When x is
;; the largest fixnum, then (+ x 1) is a bignum which needs to be
;; allocated in memory, which typically leads to more frequent garbage
;; collections.
;;
;; Note that this is only a heuristic method because it depends on the
;; implementation of the garbage collector and SRFI 124. However, it
;; has been tested to work for a variety of R7RS systems that support
;; SRFI 124:
;;
;; $ gsi determine-max-fixnum.scm
;; max-fixnum = 2305843009213693951
;; 62 bits in a fixnum
;;
;; $ chibi-scheme determine-max-fixnum.scm
;; max-fixnum = 4611686018427387903
;; 63 bits in a fixnum
;;
;; $ sagittarius determine-max-fixnum.scm
;; max-fixnum = 2305843009213693951
;; 62 bits in a fixnum

(import (scheme base) (scheme write) (scheme inexact))
(import (srfi 124))

(define (loops-for-n-gcs n thunk)
  (let loop1 ((i n) (count 0))
    (if (<= i 0)
        (quotient count n)
        (let ((eph (make-ephemeron (list i) i)))
          (let loop2 ((i i) (count count))
            (let ((new-count (+ count 1)))
              (thunk)
              (if (ephemeron-broken? eph)
                  (loop1 (- i 1) new-count)
                  (loop2 i new-count))))))))

(define (speed-of-inc x) ;; "speed" is measured as number of loops per gc
  (loops-for-n-gcs 3 (lambda () (list (+ x 1)))))

(define (determine-max-fixnum-empirically)
  (let ((threshold (quotient (* 95 (speed-of-inc 0)) 100))) ;; 95%
    (let loop ((power-of-two-minus-1 0))
      (let ((speed (speed-of-inc power-of-two-minus-1)))
        ;;(write speed)(newline)
        (if (< speed threshold)
            power-of-two-minus-1
            (loop (+ (* power-of-two-minus-1 2) 1)))))))

(define max-fixnum (determine-max-fixnum-empirically))

(display "max-fixnum = ")
(write max-fixnum)
(newline)

(write (+ 1 (exact (round (/ (log max-fixnum) (log 2))))))
(display " bits in a fixnum")
(newline)

> On Jan 26, 2024, at 11:30 AM, Bradley Lucier <xxxxxx@purdue.edu> wrote:
>
> On 1/26/24 11:01 AM, Antero Mejr wrote:
>> Bradley Lucier<xxxxxx@purdue.edu>  writes:
>>> On 1/26/24 12:27 AM, John Cowan wrote:
>>>> The disadvantage of this idea is that it would fail to test bignums at all.
>>> The current definition
>>>
>>>     (define max-int 1000000000000000001)
>>>
>>> fails to test any bignums at all on 64-bit Gambit, because 1000000000000000001
>>> is a fixnum.
>> SRFI 252 says "there are values in the [sample] implementation that may
>> need to be adjusted". That number was chosen as an arbitrarily large
>> bignum for Gauche, but implementations should change it.
>> Perhaps the SRFI should have also say: "the maximum integer value should
>> be set to generate bignums for a given implementation and CPU
>> architecture".
>> I could try to cond-expand a bignum for common CPU architectures and
>> implementations (Gauche, Chibi, Gambit, Guile 3), but I think the
>> implementer should be the one to decide the number.
>
> Well, it's a bit tricky to get it right.
>
> If you set max-int to be twice the maximum fixnum, then about half the generated numbers will be bignums (if numbers are generated uniformly in the interval), which may not be what is wanted/needed.
>
> If max-int is set to 100 times the maximum fixnum, then 99% of generated numbers will be bignums, which is probably not what someone wants.
>
> Practically, sometimes one wants fixnums and sometimes one wants bignums.  Perhaps max-int should be a parameter adjustable at runtime. Or perhaps there really should be fixnum-generator and bignum-generator.
>
> Brad
>