compiled, it does not check the types of its arguments.
@end deffn
+@deffn procedure flo:signed-lgamma x
+Returns two values,
+@iftex
+@tex
+$$m = \log \left|\Gamma(x)\right| \quad\hbox{and}\quad s = \mathop{\rm sign} \Gamma(x),$$
+@end tex
+@end iftex
+@ifnottex
+
+@example
+@group
+m = log(|Gamma(@var{x})|)
+
+and
+
+s = sign(Gamma(@var{x})),
+@end group
+@end example
+
+@end ifnottex
+respectively a flonum and an exact integer either @code{-1} or
+@code{1}, so that
+@iftex
+@tex
+$$\Gamma(x) = s \cdot e^m.$$
+@end tex
+@end iftex
+@ifnottex
+
+@example
+Gamma(x) = s * e^m.
+@end example
+
+@end ifnottex
+@end deffn
@deffn procedure flo:min x1 x2
@deffnx procedure flo:max x1 x2
FLONUM_RESULT (result);
}
+DEFINE_PRIMITIVE ("FLONUM-SIGNED-LGAMMA", Prim_flonum_signed_lgamma, 1, 1, 0)
+{
+ double x;
+ double result;
+ int sign;
+ PRIMITIVE_HEADER (1);
+
+ x = (arg_flonum (1));
+#ifdef HAVE_LGAMMA_R
+ result = (lgamma_r (x, (&sign)));
+#else
+ result = (lgamma (x));
+ sign = signgam;
+#endif
+
+ assert (LONG_TO_FIXNUM_P (sign));
+ PRIMITIVE_RETURN
+ (cons ((double_to_flonum (result)), (LONG_TO_FIXNUM (sign))));
+}
+
DEFINE_PRIMITIVE ("FLONUM-GAMMA", Prim_flonum_gamma, 1, 1, 0)
SIMPLE_TRANSCENDENTAL_FUNCTION (tgamma)
DEFINE_PRIMITIVE ("FLONUM-ERF", Prim_flonum_erf, 1, 1, 0)
(define (flo:total-order-mag x y)
(flo:total-order (flo:abs x) (flo:abs y)))
-
+\f
(define (flo:total< x y)
(if (or (flo:nan? x) (flo:nan? y))
;; Must handle NaNs first and carefully to avoid exception on
(if (and (flo:finite? x) (not (flo:safe-zero? x)))
(fix:- (cdr ((ucode-primitive flonum-normalize 1) x)) 1)
(begin (flo:raise-exceptions! (flo:exception:invalid-operation)) #f)))
+
+(define (flo:signed-lgamma x)
+ (let ((p ((ucode-primitive flonum-signed-lgamma 1) x)))
+ (values (car p) (cdr p))))
\f
;;;; Exact integers
flo:safe>
flo:safe>=
flo:sign-negative?
+ flo:signed-lgamma
flo:sin
flo:sinh
flo:snan
(assert-eqv (exact->inexact x) y)
(if (not (= x y))
(assert-except/no-traps (flo:exception:inexact-result)
- (lambda () (exact->inexact x))))))))
\ No newline at end of file
+ (lambda () (exact->inexact x))))))))
+
+(define-enumerated-test 'flo:lgamma
+ (list (list -0.123))
+ (lambda (x)
+ (receive (log-gamma sign) (flo:signed-lgamma x)
+ (assert-eqv (flo:lgamma x) log-gamma)
+ (let ((gamma (* sign (exp log-gamma))))
+ (assert-<= (relerr (flo:gamma x) gamma) 1e-15)))))
\ No newline at end of file