Subject: [clisp-list] *-float-*-epsilon in clisp

From: Stefan Kain <[email-masked]>
Date: Sun Feb 10 06:14:03 2002

Hi fellow clisp-ers,

I have written the following functions
which determine the various floating-point-epsilons.

I get discrepancies for the double-float-*-epsilon values
on my machine. I don't think, that my FP-Coprocessor is
wrong. Maybe there is just a wrong definition shipped
with clisp. If you  want to read, what this all is about,
have a look at: 

http://www.xanalys.com/software_tools/reference/HyperSpec/Body/v_short_.htm

Simply load the functions given below and enter
into the repl:

(test-epsilons)

Could you give them a try and report your results for your
local installation to clisp-list?

That would be very kind! Thanks!

Bye,
Stefan

===============================================================
(defun test-pos-epsilon (<EPSILON>)
  (= (float 1 <EPSILON>) (+ (float 1 <EPSILON>) <EPSILON>)))

(defun test-neg-epsilon (<EPSILON>)
  (= (float 1 <EPSILON>) (- (float 1 <EPSILON>) <EPSILON>)))

(defun binary-search (lower_bound upper_bound old_value precision test-fun)
  (let* ((new_bound (/ (+ (float lower_bound precision)
                          (float upper_bound precision)) 2))
         (new_value (float new_bound precision)))
    (if (= old_value new_value)
      ;; then
      ;; (format t "~A ~A~%" old_string new_string)
      (float upper_bound precision)
      ;; else
      (progn 
        ;;  (format t "~A ~A~%" (float lower_bound precision)
        ;;          (float upper_bound precision))
        (if (funcall test-fun new_bound)
          ;; then
          (binary-search new_bound upper_bound new_value
                         precision test-fun)
          ;; else
          (binary-search lower_bound new_bound new_value
                         precision test-fun))))))

;;;; test:      
(defun test-epsilons ()
  (let ((fmt "~30E~30E~30E~%"))
    (format t "~30<~A~>~30<~A~>~30<~A~>~%"
            "system value"
            "computed value"
            "difference")

    ;; short-float-epsilon:
    (format t "short-float-epsilon:~%")
    (format t fmt
            short-float-epsilon
            (binary-search 0.0 1.0 0.0 1.0s0 #'test-pos-epsilon)
            (- (binary-search 0.0 1.0 0.0 1.0s0 #'test-pos-epsilon)
               short-float-epsilon))

    ;; short-float-negative-epsilon:
    (format t "short-float-negative-epsilon:~%")
    (format t fmt 
            short-float-negative-epsilon
            (binary-search 0.0 1.0 0.0 1.0s0 #'test-neg-epsilon)
            (- (binary-search 0.0 1.0 0.0 1.0s0 #'test-neg-epsilon)
               short-float-negative-epsilon))

    ;; single-float-epsilon:
    (format t "single-float-epsilon:~%")
    (format t fmt 
            single-float-epsilon
            (binary-search 0.0 1.0 0.0 1.0 #'test-pos-epsilon)
            (- (binary-search 0.0 1.0 0.0 1.0 #'test-pos-epsilon)
               single-float-epsilon))

    ;; single-float-negative-epsilon:
    (format t "single-float-negative-epsilon:~%")
    (format t fmt 
            single-float-negative-epsilon
            (binary-search 0.0 1.0 0.0 1.0 #'test-neg-epsilon)
            (- (binary-search 0.0 1.0 0.0 1.0 #'test-neg-epsilon)
               single-float-negative-epsilon))

    ;; double-float-epsilon:
    (format t "double-float-epsilon:~%")
    (format t fmt
            double-float-epsilon
            (binary-search 0.0 1.0 0.0 1.0d0 #'test-pos-epsilon)
            (- (binary-search 0.0 1.0 0.0 1.0d0 #'test-pos-epsilon)
               double-float-epsilon))

    ;; double-float-negative-epsilon:
    (format t "double-float-negative-epsilon:~%")
    (format t fmt
            double-float-negative-epsilon
            (binary-search 0.0 1.0 0.0 1.0d0 #'test-neg-epsilon)
            (- (binary-search 0.0 1.0 0.0 1.0d0 #'test-neg-epsilon)
               double-float-negative-epsilon))

    ;; long-float-epsilon:
    (format t "long-float-epsilon:~%")
    (format t fmt 
            long-float-epsilon
            (binary-search 0.0 1.0 0.0 1.0l0 #'test-pos-epsilon)
            (- (binary-search 0.0 1.0 0.0 1.0l0 #'test-pos-epsilon)
               long-float-epsilon))

    ;;long-float-negative-epsilon:
    (format t "long-float-negative-epsilon:~%")
    (format t fmt
            long-float-negative-epsilon
            (binary-search 0.0 1.0 0.0 1.0l0 #'test-neg-epsilon)
            (- (binary-search 0.0 1.0 0.0 1.0l0 #'test-neg-epsilon)
               long-float-negative-epsilon))))

---

From: Arseny Slobodjuck <[email-masked]>
Date: Sun Feb 10 20:48:03 2002

Hello, Stefan,

Monday, February 11, 2002, 12:14:42 AM, you wrote:

Stefan> Could you give them a try and report your results for your
Stefan> local installation to clisp-list?

A week old Clisp from CVS on NT4.0:

                  system value                computed value                    difference
short-float-epsilon:
                     7.6295s-6                     7.6295s-6                        0.0s+0
short-float-negative-epsilon:
                    3.81477s-6                    3.81477s-6                        0.0s+0
single-float-epsilon:
                   5.960465E-8                   5.960465E-8                        0.0E+0
single-float-negative-epsilon:
                  2.9802325E-8                  2.9802325E-8                        0.0E+0
double-float-epsilon:
        1.1102230246251567d-16        1.1102230246251567d-16                        0.0d+0
double-float-negative-epsilon:
         5.551115123125784d-17         5.551115123125784d-17                        0.0d+0
long-float-epsilon:
     5.4210108624275221706L-20     5.4210108624275221706L-20                        0.0L+0
long-float-negative-epsilon:
     2.7105054312137610853L-20     2.7105054312137610853L-20                        0.0L+0

-- 
Best regards,
 Arseny                            mailto:[email-masked]

---

From: Sam Steingold <[email-masked]>
Date: Mon Feb 11 12:23:02 2002

> * In message <[email-masked]>
> * On the subject of "[clisp-list] *-float-*-epsilon in clisp"
> * Sent on Sun, 10 Feb 2002 15:14:42 +0100
> * Honorable Stefan Kain <[email-masked]> writes:
>
> on my machine.

this is specific to linux on i386 (the fpu uses 80 bit floats).

apply the appended patch and rebuild _both_ lisp.run and lispinit.mem

please report your experiences

-- 
Sam Steingold (http://www.podval.org/~sds) running RedHat7.2 GNU/Linux
Keep Jerusalem united! <http://www.onejerusalem.org/Petition.asp>
Read, think and remember! <http://www.iris.org.il> <http://www.memri.org/>
The early worm gets caught by the bird.

--- lisparit.d.~1.30.~	Mon Nov 19 18:49:08 2001
+++ lisparit.d	Mon Feb 11 15:07:07 2002
@@ -2253,6 +2253,8 @@
         var object obj;
         #ifdef intQsize
         encode_DF(0,-DF_mant_len,bit(DF_mant_len)+1, obj=);
+        #elif (defined(unix) && defined(linux) && defined(i386))
+        encode2_DF(0,-DF_mant_len,bit(DF_mant_len-32)|bit(DF_mant_len-32-DF_exp_len),1, obj=);
         #else
         encode2_DF(0,-DF_mant_len,bit(DF_mant_len-32),1, obj=);
         #endif
@@ -2262,6 +2264,8 @@
         var object obj;
         #ifdef intQsize
         encode_DF(0,-DF_mant_len-1,bit(DF_mant_len)+1, obj=);
+        #elif (defined(unix) && defined(linux) && defined(i386))
+        encode2_DF(0,-DF_mant_len-1,bit(DF_mant_len-32)|bit(DF_mant_len-32-DF_exp_len),1, obj=);
         #else
         encode2_DF(0,-DF_mant_len-1,bit(DF_mant_len-32),1, obj=);
         #endif