Also expose those predicates in Scheme, and implement flo:eqv? properly.
bool
flonum_is_finite_p (SCHEME_OBJECT x)
{
- return double_is_finite_p (FLONUM_TO_DOUBLE (x));
-}
-
-bool
-double_is_finite_p (double x)
-{
- return
- (((x > 1.0) || (x < -1.0))
- ? (x != (x / 2.0))
- : ((x <= 1.0) && (x >= -1.0)));
+ return (isfinite (FLONUM_TO_DOUBLE (x)));
}
bool
extern SCHEME_OBJECT integer_shift_left (SCHEME_OBJECT, unsigned long);
extern SCHEME_OBJECT integer_shift_right (SCHEME_OBJECT, unsigned long);
-extern bool double_is_finite_p (double);
extern SCHEME_OBJECT double_to_flonum (double);
extern bool real_number_to_double_p (SCHEME_OBJECT);
extern double real_number_to_double (SCHEME_OBJECT);
}
}
\f
+/* C99 flonum predicates */
+
+DEFINE_PRIMITIVE ("FLONUM-IS-FINITE?", Prim_flonum_is_finite_p, 1, 1, 0)
+{
+ PRIMITIVE_HEADER (1);
+ PRIMITIVE_RETURN (BOOLEAN_TO_OBJECT (isfinite (arg_flonum (1))));
+}
+
+DEFINE_PRIMITIVE ("FLONUM-IS-INFINITE?", Prim_flonum_is_infinite_p, 1, 1, 0)
+{
+ PRIMITIVE_HEADER (1);
+ PRIMITIVE_RETURN (BOOLEAN_TO_OBJECT (isinf (arg_flonum (1))));
+}
+
+DEFINE_PRIMITIVE ("FLONUM-IS-NAN?", Prim_flonum_is_nan_p, 1, 1, 0)
+{
+ PRIMITIVE_HEADER (1);
+ PRIMITIVE_RETURN (BOOLEAN_TO_OBJECT (isnan (arg_flonum (1))));
+}
+
+DEFINE_PRIMITIVE ("FLONUM-IS-NORMAL?", Prim_flonum_is_normal_p, 1, 1, 0)
+{
+ PRIMITIVE_HEADER (1);
+ PRIMITIVE_RETURN (BOOLEAN_TO_OBJECT (isnormal (arg_flonum (1))));
+}
+
+DEFINE_PRIMITIVE ("FLONUM-IS-NEGATIVE?", Prim_flonum_is_negative_p, 1, 1, 0)
+{
+ PRIMITIVE_HEADER (1);
+ PRIMITIVE_RETURN (BOOLEAN_TO_OBJECT (signbit (arg_flonum (1))));
+}
+
+DEFINE_PRIMITIVE ("FLONUM-IS-GREATER?", Prim_flonum_is_greater_p, 2, 2, 0)
+{
+ PRIMITIVE_HEADER (2);
+ PRIMITIVE_RETURN
+ (BOOLEAN_TO_OBJECT (isgreater ((arg_flonum (1)), (arg_flonum (2)))));
+}
+
+DEFINE_PRIMITIVE ("FLONUM-IS-GREATER-OR-EQUAL?", Prim_flonum_is_greater_or_equal_p, 2, 2, 0)
+{
+ PRIMITIVE_HEADER (2);
+ PRIMITIVE_RETURN
+ (BOOLEAN_TO_OBJECT (isgreaterequal ((arg_flonum (1)), (arg_flonum (2)))));
+}
+
+DEFINE_PRIMITIVE ("FLONUM-IS-LESS-OR-EQUAL?", Prim_flonum_is_less_or_equal_p, 2, 2, 0)
+{
+ PRIMITIVE_HEADER (2);
+ PRIMITIVE_RETURN
+ (BOOLEAN_TO_OBJECT (islessequal ((arg_flonum (1)), (arg_flonum (2)))));
+}
+
+DEFINE_PRIMITIVE ("FLONUM-IS-LESS?", Prim_flonum_is_less_p, 2, 2, 0)
+{
+ PRIMITIVE_HEADER (2);
+ PRIMITIVE_RETURN
+ (BOOLEAN_TO_OBJECT (isless ((arg_flonum (1)), (arg_flonum (2)))));
+}
+
+DEFINE_PRIMITIVE ("FLONUM-IS-LESS-OR-GREATER?", Prim_flonum_is_less_or_greater_p, 2, 2, 0)
+{
+ PRIMITIVE_HEADER (2);
+ PRIMITIVE_RETURN
+ (BOOLEAN_TO_OBJECT (islessgreater ((arg_flonum (1)), (arg_flonum (2)))));
+}
+
+DEFINE_PRIMITIVE ("FLONUM-IS-UNORDERED?", Prim_flonum_is_unordered_p, 2, 2, 0)
+{
+ PRIMITIVE_HEADER (2);
+ PRIMITIVE_RETURN
+ (BOOLEAN_TO_OBJECT (isunordered ((arg_flonum (1)), (arg_flonum (2)))));
+}
+\f
/* Miscellaneous floating-point operations */
DEFINE_PRIMITIVE ("FLONUM-COPYSIGN", Prim_flonum_copysign, 2, 2, 0)
(let ((p flo:significand-digits-base-2))
(rat:* (flo:->integer (flo:denormalize f p))
(rat:expt 2 (int:- e-p p)))))))
-
-(define (flo:nan? x)
- (not (or (flo:positive? x)
- (flo:negative? x)
- (flo:zero? x))))
\f
(define (real:real? object)
(or (flonum? object)
(flo:zero? flonum-zero? 1)
(flo:positive? flonum-positive? 1)
(flo:negative? flonum-negative? 1)
+ (flo:finite? flonum-is-finite? 1)
+ (flo:infinite? flonum-is-infinite? 1)
+ (flo:nan? flonum-is-nan? 1)
+ (flo:normal? flonum-is-normal? 1)
+ (flo:safe-negative? flonum-is-negative? 1)
(flo:= flonum-equal? 2)
(flo:< flonum-less? 2)
(flo:> flonum-greater? 2)
+ (flo:safe> flonum-is-greater? 2)
+ (flo:safe>= flonum-is-greater-or-equal? 2)
+ (flo:safe< flonum-is-less? 2)
+ (flo:safe<= flonum-is-less-or-equal? 2)
+ (flo:safe<> flonum-is-less-or-greater? 2)
+ (flo:unordered? flonum-is-unordered? 2)
(flo:+ flonum-add 2)
(flo:- flonum-subtract 2)
(flo:* flonum-multiply 2)
((flo:= x y) y)
(else (error:bad-range-argument (if (flo:finite? x) x y) 'flo:max))))
-;;; XXX FLO:FINITE?, FLO:NAN?, FLO:EQV?, &c., are cute, but should be
-;;; replaced by primitives.
-
-(define (flo:finite? x)
- (if (or (flo:> x 1.) (flo:< x -1.))
- (not (flo:= x (flo:/ x 2.)))
- (and (flo:<= x 1.) (flo:>= x -1.))))
-
(define (flo:eqv? x y)
- ;; (bit-string=? (flo:->bit-string x) (flo:->bit-string y))
- (if (flo:= x y)
- (or (not (flo:zero? x))
- ;; XXX Kludgey but expedient test for zero sign.
- (flo:= (flo:atan2 x -1.) (flo:atan2 y -1.)))
- ;; XXX (and (flo:nan? x) (flo:nan? y) ...)
- #f))
+ (and (not (flo:nan? x))
+ (not (flo:nan? y))
+ (flo:= x y)
+ (or (not (flo:zero? x))
+ (eq? (flo:safe-negative? x)
+ (flo:safe-negative? y)))))
(define (int:->flonum n)
((ucode-primitive integer->flonum 2) n #b10))
flo:floor->exact
flo:gamma
flo:hypot
+ flo:infinite?
flo:j0
flo:j1
flo:jn
flo:max
flo:min
flo:modulo
+ flo:nan?
flo:negate
flo:negative?
flo:nextafter
+ flo:normal?
flo:positive?
flo:round
flo:round->exact
+ flo:safe-negative?
+ flo:safe<
+ flo:safe<=
+ flo:safe<>
+ flo:safe>
+ flo:safe>=
flo:sin
flo:sinh
flo:sqrt
flo:tanh
flo:truncate
flo:truncate->exact
+ flo:unordered?
flo:vector-cons
flo:vector-length
flo:vector-ref
cube
exact-nonnegative-integer?
exact-positive-integer?
- flo:nan?
flo:significand-digits-base-10
flo:significand-digits-base-2
flonum-unparser-cutoff