Next: , Previous: , Up: srfi comparators constructors   [Index]


2.38.8.2 Inexact real comparators

Function: make-inexact-real-comparator epsilon rounding nan-handling

Return a comparator that compares inexact real numbers including NaNs as follows: if after rounding to the nearest epsilon they are the same, they compare equal; otherwise they compare as specified by <.

The direction of rounding is specified by the rounding argument, which is either a procedure accepting two arguments (the number and epsilon), or else one of the symbols floor, ceiling, truncate, or round.

The value of epsilon is used by the generated comparator only if rounding is a procedure: it is ignored if rounding is a symbol. When epsilon is not #f and rounding is a symbol: this function raises a continuable exception with compound condition object of types: &inexact-real-comparator-with-unused-epsilon, &who, &message, &irritants.

The argument nan-handling specifies how to compare NaN arguments to non–NaN arguments.

Here is an example of comparator using the round rounding mode and the error policy to compare +nan.0:

#!vicare
(import (vicare) (srfi :114))

(define-constant C
  (make-inexact-real-comparator #f 'round 'error))

;; type test
(comparator-test-type C 1.2)    ⇒ #t
(comparator-test-type C "ciao") ⇒ #f
(comparator-test-type C 1+2i)   ⇒ #f

;; type check
(comparator-check-type C 1.2)   ⇒ #t
(try
    (comparator-check-type C (void))
  (catch E
    ((&comparator-type-error)
     #t)
    (else #f)))
⇒ #t

;; comparison
(comparator-compare C 1.2 1.2)          ⇒  0
(comparator-compare C 1.0 2.0)          ⇒ -1
(comparator-compare C 2.0 1.0)          ⇒ +1

(comparator-compare C +inf.0 +inf.0)    ⇒ 0
(comparator-compare C -inf.0 -inf.0)    ⇒ 0
(comparator-compare C -inf.0 +inf.0)    ⇒ -1
(comparator-compare C +inf.0 -inf.0)    ⇒ +1

(comparator-compare C +nan.0 +nan.0)    ⇒ 0
(try
    (comparator-compare C +nan.0 1.0)
  (catch E
    ((&comparator-nan-comparison-error)
     #t)
    (else E)))
⇒ #t
(try
    (comparator-compare C 1.0 +nan.0)
  (catch E
    ((&comparator-nan-comparison-error)
     #t)
    (else E)))
⇒ #t

;; comparison with rounding
(comparator-compare C 1.04 1.0) ⇒ 0
(comparator-compare C 0.96 1.0) ⇒ 0

;; hash
(= (comparator-hash C 1.0) (comparator-hash C 1.04))      ⇒ #t
(= (comparator-hash C 1.0) (comparator-hash C 0.96))      ⇒ #t
(non-negative-exact-integer? (comparator-hash C +inf.0))  ⇒ #t
(non-negative-exact-integer? (comparator-hash C -inf.0))  ⇒ #t
(non-negative-exact-integer? (comparator-hash C +nan.0))  ⇒ #t

Here is an example of comparator that rounds to the nearest 0.1 and uses the min policy to compare +nan.0:

#!vicare
(import (vicare) (srfi :114))

(define* (round-to-epsilon {R flonum?} {epsilon flonum?})
  (infix round(R / epsilon) * epsilon))

(define-constant C
  (make-inexact-real-comparator 0.1 round-to-epsilon 'min))

;; rounding to
(round-to-epsilon 1.0   0.1)    ⇒ 1.0
(round-to-epsilon 1.05  0.1)    ⇒ 1.0
(round-to-epsilon 0.951 0.1)    ⇒ 1.0
(round-to-epsilon 0.949 0.1)    ⇒ 0.9

;; type test
(comparator-test-type C 1.2)    ⇒ #t
(comparator-test-type C +inf.0) ⇒ #t
(comparator-test-type C -inf.0) ⇒ #t
(comparator-test-type C -nan.0) ⇒ #t
(comparator-test-type C "ciao") ⇒ #f
(comparator-test-type C 1+2i)   ⇒ #f

;; type check
(comparator-check-type C 1.2)   ⇒ #t
(try
    (comparator-check-type C (void))
  (catch E
    ((&comparator-type-error)
     #t)
    (else E)))
⇒ #t

;; comparison
(comparator-compare C 1.2 1.2)          ⇒ 0
(comparator-compare C 1.0 2.0)          ⇒ -1
(comparator-compare C 2.0 1.0)          ⇒ +1

(comparator-compare C +inf.0 +inf.0)    ⇒ 0
(comparator-compare C -inf.0 -inf.0)    ⇒ 0
(comparator-compare C -inf.0 +inf.0)    ⇒ -1
(comparator-compare C +inf.0 -inf.0)    ⇒ +1

(comparator-compare C +nan.0 +nan.0)    ⇒ 0
(comparator-compare C +nan.0 1.0)       ⇒ -1
(comparator-compare C 1.0 +nan.0)       ⇒ +1

;; comparison with rounding
(comparator-compare C 1.04  1.0)        ⇒ 0
(comparator-compare C 0.96  1.0)        ⇒ 0
(comparator-compare C 0.951 1.0)        ⇒ 0
(comparator-compare C 0.949 1.0)        ⇒ -1
(comparator-compare C 0.949 0.9)        ⇒ 0

;; hash
(= (comparator-hash C 1.0)  (comparator-hash C 1.04))     ⇒ #t
(= (comparator-hash C 1.0)  (comparator-hash C 0.96))     ⇒ #t
(= (comparator-hash C 1.0)  (comparator-hash C 0.951))    ⇒ #t
(= (comparator-hash C 1.04) (comparator-hash C 0.951))    ⇒ #t
(non-negative-exact-integer? (comparator-hash C +inf.0))  ⇒ #t
(non-negative-exact-integer? (comparator-hash C -inf.0))  ⇒ #t
(non-negative-exact-integer? (comparator-hash C +nan.0))  ⇒ #t

Here is an example of comparator using the max policy to compare +nan.0:

#!vicare
(import (vicare) (srfi :114))

(define-constant C
  (make-inexact-real-comparator #f 'round 'max))

(comparator-compare C +nan.0 +nan.0)    ⇒ 0
(comparator-compare C +nan.0 1.0)       ⇒ +1
(comparator-compare C 1.0 +nan.0)       ⇒ -1

Here is an example of comparator using a procedure as policy to compare +nan.0:

#!vicare
(import (vicare) (srfi :114))

(define (nan-comparison other-R)
  ;;NaN is equal to any number.
  ;;
  0)

(define-constant C
  (make-inexact-real-comparator #f 'round nan-comparison))

(comparator-compare C +nan.0 +nan.0)    ⇒ 0
(comparator-compare C +nan.0 +1.0)      ⇒ 0
(comparator-compare C +1.0   +nan.0)    ⇒ 0

Next: , Previous: , Up: srfi comparators constructors   [Index]