Optional comparator issue
Shiro Kawai
(06 Apr 2014 18:20 UTC)
|
srfi-114 reference implementation fixes Shiro Kawai (14 Oct 2014 12:55 UTC)
|
Another srfi-114 reference implementation issue
Shiro Kawai
(23 Oct 2014 19:23 UTC)
|
Re: srfi-114 reference implementation fixes
John Cowan
(16 Nov 2014 16:03 UTC)
|
srfi-114 reference implementation fixes Shiro Kawai 14 Oct 2014 12:35 UTC
I think there's a couple of issues in the reference implementation of make-indexact-real-comparator: (1) When /rounding/ argument is a procedure, it is invoked with a single argument (/ x epsilon), while the srfi-114 document says it should be called with two arguments, x and epsilon. (2) It uses inexact-real-hash for the hash function, which delegates to number-hash to hash numbers. However, the hash function should take the rounding mode into account, to satisfy the constraint that hash values for x and y must be equal when x and y are equal w.r.t. the compare procedure. A suggested patch follows; though I haven't tested it (Gauche has independent implementation for comparators). *** comparators/constructors.scm Tue Oct 14 02:24:25 2014 --- comparators/constructors.scm.orig Fri Aug 15 14:10:36 2014 *************** *** 77,94 **** ;; Return an appropriately rounded number (define (rounded x symbol) ! (case symbol ! ((round) (round x)) ! ((ceiling) (ceiling x)) ! ((floor) (floor x)) ! ((truncate) (truncate x)) (else (error "invalid rounding specification" symbol)))) ;; Return a number appropriately rounded to epsilon (define (rounded-to x epsilon symbol) ! (if (procedure? symbol) ! (symbol x epsilon) ! (rounded (/ x epsilon) symbol))) ;; Returns result of comparing a NaN with a non-NaN (define (nan-comparison nan-handling which other) --- 77,93 ---- ;; Return an appropriately rounded number (define (rounded x symbol) ! (cond ! ((procedure? symbol) (symbol x)) ! ((eq? symbol 'round) (round x)) ! ((eq? symbol 'ceiling) (ceiling x)) ! ((eq? symbol 'floor) (floor x)) ! ((eq? symbol 'truncate) (truncate x)) (else (error "invalid rounding specification" symbol)))) ;; Return a number appropriately rounded to epsilon (define (rounded-to x epsilon symbol) ! (rounded (/ x epsilon) symbol)) ;; Returns result of comparing a NaN with a non-NaN (define (nan-comparison nan-handling which other) *************** *** 116,131 **** (rounded-to b epsilon rounding))))))) ;; Return 0 for NaN, number-hash otherwise ! (define (make-inexact-real-hash epsilon symbol) ! (lambda (obj) ! (if (nan? obj) 0 (number-hash (rounded-to obj epsilon symbol))))) (define (make-inexact-real-comparator epsilon rounding nan-handling) (make-comparator inexact-real? #t (make-inexact-real-comparison epsilon rounding nan-handling) ! (make-inexact-real-hash epsilon rounding))) ;;; Sequence comparator constructors and comparators ;;; The hash functions are based on djb2, but --- 115,129 ---- (rounded-to b epsilon rounding))))))) ;; Return 0 for NaN, number-hash otherwise ! (define (inexact-real-hash obj) ! (if (nan? obj) 0 (number-hash obj))) (define (make-inexact-real-comparator epsilon rounding nan-handling) (make-comparator inexact-real? #t (make-inexact-real-comparison epsilon rounding nan-handling) ! inexact-real-hash)) ;;; Sequence comparator constructors and comparators ;;; The hash functions are based on djb2, but