Changeset 42 for trunk/floating-point

Show
Ignore:
Timestamp:
03/21/08 19:00:24 (8 months ago)
Author:
lhealy
Message:

Enhance #'float-as-integer and #'integer-as-float to produce or take
an IEEE754 integer instead of just a sequence integer. The
IEEE754 integer is the unsigned version of the sequence integer,
with the sign marked in the high order bit.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/floating-point/floating-point.lisp

    r26 r42  
    1 ;; Comparison of floating point numbers 
     1;; Comparison of floating point numbers using sequence integers 
    22;; Liam Healy 2008-01-22 19:00:17EST floating-point.lisp 
    3 ;; Time-stamp: <2008-01-29 21:34:52EST floating-point.lisp> 
     3;; Time-stamp: <2008-03-21 15:04:15EDT floating-point.lisp> 
    44;; $Id$ 
     5 
     6;;; All floats can be represented by integers.  There are two slightly 
     7;;; different ways of doing this.  The sequence integer 
     8;;; has the same sign as the float; the IEEE754 integer is the 
     9;;; unsigned version of the sequence integer, with the sign marked in 
     10;;; the high order bit.  The sequence integer is used for comparing 
     11;;; numbers, where order preservation is important; the IEEE754 integer 
     12;;; is used when reading a float storage location as an integer. 
    513 
    614(in-package :gsl) 
     
    4755            (if (minusp sign) 1 0) expbits exp sigbits mant))) 
    4856 
    49 (defun float-as-integer (float) 
    50   "An integer corresponding to the float which satisfies three properties: 
     57(defun ieee754-sign-bit (float-type) 
     58  "The bytespec to access the sign bit in the IEEE754 specification." 
     59  (byte 1 (if (eq float-type 'double-float) 63 31))) 
     60                   
     61(defun float-as-integer (float &optional ieee754) 
     62  "The sequence integer corresponding to the float  
     63   which satisfies three properties:  
    5164   1) For two floats (< a b), then 
    5265      (< (float-as-integer a) (float-as-integer b)). 
     
    5669   The absolute value of the integer is the integer of the 
    5770   IEEE754 representation without the sign bit, and the 
    58    sign of the integer agrees with the sign of the float." 
     71   sign of the integer agrees with the sign of the float. 
     72   To get the IEEE754 integer, specify 'single-float or  
     73   'double-float to ieee754." 
    5974  (multiple-value-bind (mant exp sign sigbits expbits) 
    6075      (decode-ieee754 float) 
    6176    (declare (ignore expbits)) 
    62     (* sign (+ (ash exp sigbits) mant)))) 
     77    (if ieee754 
     78        (* (dpb 1 (ieee754-sign-bit ieee754) (+ (ash exp sigbits) mant))) 
     79        (* sign (+ (ash exp sigbits) mant))))) 
    6380 
    6481;; (float-as-integer most-negative-single-float) 
     
    8097 
    8198(defun integer-as-float (integer float-type) 
    82   "Construct the floating point number from its integer representation. 
    83    Also return the number in rational form." 
     99  "Construct the floating point number from its integer representation,  
     100   either sequence or IEEE754. 
     101   Also return the number in rational form. 
     102   The integer may be either a signed integer produced by 
     103   float-as-integer, or an IEEE754 integer.  Acceptable 
     104   float-type is either 'double-float or 'single-float." 
    84105  (let ((expbits (if (eq float-type 'double-float) 11 8)) 
    85106        (sigbits (if (eq float-type 'double-float) 52 23))) 
     
    97118                  0))) 
    98119      (let ((result 
    99              (* (signum integer)        ; preserve the sign 
     120             (* (signum integer)        ; accept negative integer 
     121                (if                     ; accept IEEE754 negative 
     122                 (ldb-test 
     123                  (ieee754-sign-bit float-type) 
     124                  pinteger) 
     125                 -1 1) 
    100126                (expt 2 (- bexponent (1- (expt 2 (1- expbits))))) 
    101127                frac)))