Changeset 5670


Ignore:
Timestamp:
Jan 2, 2007, 5:59:19 AM (18 years ago)
Author:
Gary Byers
Message:

Don't assume that fixnums can be accurately coerced to floats when comparing
fixnums and floats; do the logical equvalent of calling RATIONAL on the float
instead.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/level-0/l0-numbers.lisp

    r5586 r5670  
    424424
    425425
    426 ;; gary's more better idea
    427426(defun fixnum-dfloat-compare (int dfloat)
    428   (declare (double-float dfloat))
     427  (declare (double-float dfloat) (fixnum int))
    429428  (if (and (eq int 0)(= dfloat 0.0d0))
    430429    0
    431     (with-stack-double-floats ((tem int))
    432       (if (= tem dfloat)
    433         0
    434         (if (< tem dfloat) -1 1)))))
     430    ;; Whatever we do here should have the effect
     431    ;; of comparing the integer to the result of calling
     432    ;; RATIONAL on the float.  We could probably
     433    ;; skip the call to RATIONAL in more cases,
     434    ;; but at least check the obvious ones here
     435    ;; (e.g. different signs)
     436    (multiple-value-bind (mantissa exponent sign)
     437        (integer-decode-double-float dfloat)
     438      (declare (type (integer -1 1) sign)
     439               (fixnum exponent))
     440      (cond ((zerop int)
     441             (- sign))
     442            ((and (< int 0) (eql sign 1)) -1)
     443            ((and (> int 0) (eql sign -1)) 1)
     444            (t
     445             ;; See RATIONAL.  Can probably avoid this if
     446             ;; magnitudes are clearly dissimilar.
     447             (if (= sign -1) (setq mantissa (- mantissa)))
     448             (let* ((rat (if (< exponent 0)
     449                           (/ mantissa (ash 1 (the fixnum (- exponent))))
     450                           (ash mantissa exponent))))
     451               (if (< int rat)
     452                 -1
     453                 (if (eq int rat)
     454                   0
     455                   1))))))))
    435456
    436457
    437458
    438459(defun fixnum-sfloat-compare (int sfloat)
    439   (declare (short-float sfloat))
     460  (declare (short-float sfloat) (fixnum int))
    440461  (if (and (eq int 0)(= sfloat 0.0s0))
    441462    0
    442     #+ppc32-target
    443     (ppc32::with-stack-short-floats ((tem int))
    444       (if (= tem sfloat)
    445         0
    446         (if (< tem sfloat) -1 1)))
    447     #+64-bit-target
    448     (let* ((tem (%int-to-sfloat int)))
    449       (declare (single-float tem))
    450       (if (= tem sfloat)
    451         0
    452         (if (< tem sfloat) -1 1)))))
     463    ;; Whatever we do here should have the effect
     464    ;; of comparing the integer to the result of calling
     465    ;; RATIONAL on the float.  We could probably
     466    ;; skip the call to RATIONAL in more cases,
     467    ;; but at least check the obvious ones here
     468    ;; (e.g. different signs)
     469    (multiple-value-bind (mantissa exponent sign)
     470        (integer-decode-short-float sfloat)
     471      (declare (type (integer -1 1) sign)
     472               (fixnum exponent))
     473      (cond ((zerop int)
     474             (- sign))
     475            ((and (< int 0) (eql sign 1)) -1)
     476            ((and (> int 0) (eql sign -1)) 1)
     477            (t
     478             ;; See RATIONAL.  Can probably avoid this if
     479             ;; magnitudes are clearly dissimilar.
     480             (if (= sign -1) (setq mantissa (- mantissa)))
     481             (let* ((rat (if (< exponent 0)
     482                           (/ mantissa (ash 1 (the fixnum (- exponent))))
     483                           (ash mantissa exponent))))
     484               (if (< int rat)
     485                 -1
     486                 (if (eq int rat)
     487                   0
     488                   1))))))))
    453489
    454490
Note: See TracChangeset for help on using the changeset viewer.