racket/collects/math/scribblings/math-bigfloat.scrbl
Matthew Flatt eaf68e6e85 GMP and MPFR as pre-build libraries for Mac OS X and Windows
Also, add versions for Unix references, and adjust the way that
missing bindings are handled.
2012-11-16 22:21:54 -07:00

734 lines
32 KiB
Racket
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#lang scribble/manual
@(require scribble/eval
racket/sandbox
(for-label racket/base
math
(only-in typed/racket/base
Flonum Real Boolean Integer Exact-Rational Exact-Positive-Integer
Any U Listof String False Values Path-String))
"utils.rkt")
@(define untyped-eval (make-untyped-math-eval))
@interaction-eval[#:eval untyped-eval (require math/bigfloat)]
@title[#:tag "bigfloat"]{Arbitrary-Precision Floating-Point Numbers (@deftech{Bigfloats})}
@(author-neil)
@defmodule[math/bigfloat]
This library provides a Typed Racket interface to @hyperlink["http://www.mpfr.org/"]{MPFR},
a C library that provides
@itemlist[@item{A C type of arbitrary-precision floating-point numbers.}
@item{Elementary and special functions that are efficient and proved correct.}
@item{Well-defined semantics that correspond with the latest IEEE 754 standard.}
]
The arbitrary-precision floating-point numbers MPFR provides and operates on are
represented by the type @racket[Bigfloat].
MPFR is free, license-compatible with commercial software, and
@hyperlink["http://www.mpfr.org/ports.html"]{easy to install} on all
major platforms. Even so, not all systems have it, so @racketmodname[math/bigfloat] links
against MPFR lazily.
If you know MPFR is installed but can't use @racketmodname[math/bigfloat], see @secref{loading}.
@section[#:tag "quick"]{Quick Start}
@itemlist[#:style 'ordered
@item{Set the working precision using @racket[(bf-precision <some-number-of-bits>)].}
@item{Use @racket[bf] to convert real values and well-formed strings to bigfloats.}
@item{Operate on bigfloats using @racket[bf]-prefixed functions like @racket[bf+] and @racket[bfsin].}
@item{Convert bigfloats to real values using @racket[bigfloat->real], @racket[bigfloat->flonum],
and @racket[bigfloat->integer]. Format them for display using @racket[bigfloat->string].}
]
For examples, continue through the FAQ.
@section{Fictionally Asked Questions}
@bold{Why use @racketmodname[math/bigfloat]}?
There are a few reasons.
@italic{Reason:} Flonums have either too much or too little precision for your application.
@examples[#:eval
untyped-eval
(flsqrt 3.0)
pi
(bf-precision 16)
(eval:alts (bfsqrt (bf 3))
(eval:result @racketresultfont{(bf #e1.73206)}))
(bf-precision 179)
(eval:alts
pi.bf
(eval:result
@racketresultfont{(bf #e3.141592653589793238462643383279502884197169399375105819)}))]
A flonum has a 53-bit significand (we'll say it has 53 bits of
@italic{precision}) and an 11-bit @italic{exponent}. A bigfloat
has an arbitrary precision of at least 2 bits and a 31-bit exponent.
@italic{Reason:} To compute ridiculously large or small numbers with confidence.
@examples[#:eval
untyped-eval
(bf-precision 128)
(eval:alts
(bfexp (bfexp (bfexp (bf 3))))
(eval:result @racketresultfont{(bf "2.050986436051648895105860942072054674579e229520860")}))
(eval:alts
(bflog (bflog (bflog (bfexp (bfexp (bfexp (bf 3)))))))
(eval:result @racketresultfont{(bf 3)}))]
@italic{Reason:} To verify your floating-point hardware.
@hyperlink["http://en.wikipedia.org/wiki/IEEE_754-2008"]{IEEE 754-2008} stipulates
that conforming implementations must correctly round the results of all operations.
Roughly speaking, results can't be more than half a bit off, where the bit in
question is the least significant in the significand.
Of course, implementations don't always adhere to standards. For example, on my old
laptop, evaluating @(racket (exp 400)) results in @(racket 5.221469689764346e+173).
Note the last four decimal digits in the significand: @(racket 4346). But they should be @racket[4144]:
@interaction[#:eval untyped-eval
(bf-precision 53)
(eval:alts
(bigfloat->flonum (bfexp (bf 400)))
(eval:result @racketresultfont{5.221469689764144e+173}))]
My new laptop computes @(racket 5.221469689764144e+173) as it should.
@italic{Reason:} To control rounding of the least significant bit.
IEEE 754 provides for different rounding modes for the smallest bit of
a flonum result, such as round to even and round toward zero. We might use
this to implement interval arithmetic correctly, by rounding lower bounds
downward and the upper bounds upward. But there isn't a portable way to set the
rounding mode!
MPFR allows the rounding mode to be set before any operation, and
@racketmodname[math/bigfloat] exposes this capability using the parameter
@racket[bf-rounding-mode].
@bold{When shouldn't I use @racketmodname[math/bigfloat]?}
When you need raw speed. Bigfloat functions can be hundreds to thousands of times slower
than flonum functions.
That's not to say that they're @italic{inefficient}. For example, @(racket bflog)
implements the algorithm with the best known asymptotic complexity. It just doesn't
run directly on hardware, and it can't take fixed-precision-only shortcuts.
@bold{Why are there junk digits on the end of @racket[(bf 1.1)]?}
That's approximately the value of the flonum @racket[1.1]. Use @code{(bf #e1.1)} or
@code{(bf "1.1")} to make the junk go away. In general, you should prefer to convert
exact rationals and strings to bigfloats.
@bold{Why is the last digit of @racket[pi.bf] not rounded correctly?}
All the @italic{bits} but the last is exact, and the last bit is correctly rounded.
This doesn't guarantee that the last digit will be.
A decimal digit represents at most log(10)/log(2) 3.3 bits. This is an irrational
number, so the decimal/bit boundary never lines up except at the decimal point.
Thus, the last decimal digit of any bigfloat must represent fewer than 3.3 bits,
so it's wrong more often than not. But it's the last @italic{bit} that counts.
@section{Bigfloat Type and Accessors}
@defidform[Bigfloat]{
An opaque type that represents an arbitrary-precision floating-point number, or a @tech{bigfloat}.
}
@defproc[(bigfloat? [v Any]) Boolean]{
Returns @racket[#t] when @racket[v] is a bigfloat.
}
@defproc[(bigfloat-precision [x Bigfloat]) Exact-Positive-Integer]{
Returns the number of bits in the significand of @racket[x]. This is almost always
the value of @racket[(bf-precision)] when @racket[x] was created.
}
@defproc[(bigfloat-sign [x Bigfloat]) (U 0 1)]{
Returns the @italic{sign bit} of the significand of @racket[x].
@examples[#:eval untyped-eval
(eval:alts
(bigfloat-sign -1.bf)
(eval:result @racketresultfont{1}))
(eval:alts
(bigfloat-sign 0.bf)
(eval:result @racketresultfont{0}))
(eval:alts
(bigfloat-sign -0.bf)
(eval:result @racketresultfont{1}))
(eval:alts
(bigfloat-sign -inf.bf)
(eval:result @racketresultfont{1}))]
}
@deftogether[(@defproc[(bigfloat-significand [x Bigfloat]) Integer]
@defproc[(bigfloat-exponent [x Bigfloat]) Integer]
@defproc[(bigfloat-sig+exp [x Bigfloat]) (Values Integer Integer)])]{
Return the @italic{signed} significand and exponent of @racket[x].
If @racket[(values sig exp) = (bigfloat-sig+exp x)], its value as an exact rational
is @racket[(* sig (expt 2 exp))]. In fact, @racket[bigfloat->rational] converts
bigfloats to rationals in exactly this way, after ensuring that @racket[(bfrational? x)]
is @racket[#t].
}
@section{Bigfloat Parameters}
@defparam[bf-precision bits Integer]{
A parameter that determines the precision of new @racket[Bigfloat] values.
With a few noted exceptions, bigfloat functions conceptually compute in infinite
precision, round the answers to @racket[(bf-precision)] bits using
@racket[(bf-rounding-mode)], and return the rounded answers. (In practice,
they employ finite algorithms that have been painstakingly proved to be equivalent
to the aforementioned infinite process.)
This parameter has a guard that ensures @racket[(bf-precision)] is between
@racket[bf-min-precision] and @racket[bf-max-precision].
}
@defparam[bf-rounding-mode mode (U 'nearest 'zero 'up 'down)]{
A parameter that determines the rounding mode used when producing new @racket[Bigfloat] values.
}
@defthing[bf-min-precision Exact-Positive-Integer]{
Equal to @racket[2], because single-bit bigfloats can't be correctly rounded.
}
@defthing[bf-max-precision Exact-Positive-Integer]{
The largest value of @racket[(bf-precision)]. This is platform-dependent, and probably much
larger than you'll ever need.
}
@section[#:tag "construction"]{Bigfloat Construction and Conversion}
@defproc*[([(bf [x (U String Real)]) Bigfloat]
[(bf [sig Integer] [exp Integer]) Bigfloat])]{
The one-argument variant converts a string or real @racket[x] to a bigfloat.
@interaction[#:eval untyped-eval
(bf-precision 128)
(eval:alts (bf 4) (eval:result @racketresultfont{(bf 4)}))
(eval:alts
(bf 1/7)
(eval:result
@racketresultfont{(bf #e0.1428571428571428571428571428571428571426)}))
(eval:alts
(bf #e4.1)
(eval:result
@racketresultfont{(bf #e4.099999999999999999999999999999999999995)}))
(eval:alts
(bf "not a number")
(eval:result
""
""
"bf: expected a well-formed decimal number; given \"not a number\""))
(eval:alts
(bf "15e200000000")
(eval:result
@racketresultfont{(bf "1.499999999999999999999999999999999999998e200000001")}))]
In the last example, the result of @racket[(bf "15e200000000")] is displayed as a
string conversion because the exact rational number would be very large.
@margin-note{* It can be a good idea if you're testing a flonum implementation of a function
against a bigfloat implementation.}
Converting from flonum literals is usually a bad idea* because flonums have only
53 bits precision. Prefer to pass exact rationals and strings to @racket[bf].
The two-argument variant converts a signed significand @racket[sig] and a power of
2 @racket[exp] to a bigfloat. Generally, @racket[(bf sig exp) = (bf (* sig (expt 2 exp)))],
but the two-argument variant is much faster, especially for large @racket[exp].
@examples[#:eval untyped-eval
(eval:alts
(bf 200 56)
(eval:result @racketresultfont{(bf 14411518807585587200)}))
(eval:alts
(bf (* 200 (expt 2 56)))
(eval:result @racketresultfont{(bf 14411518807585587200)}))]
The @racket[bfrandom] function generates random bigfloats between 0 and 1 using
the two-argument variant in this way:
@interaction[#:eval untyped-eval
(require (only-in math/base random-bits))
(bf-precision 64)
(eval:alts
(bf (random-bits 64) -64)
(eval:result @racketresultfont{(bf #e0.416872969910248753552)}))]
}
@defproc[(bfrandom) Bigfloat]{
Returns a uniformly distributed random bigfloat @racket[x] such that
@racket[(0.bf . bf<= . x)] and @racket[(x . bf< . 1.bf)].
}
@defproc[(bfcopy [x Bigfloat]) Bigfloat]{
Returns the @racket[(bf-precision)]-bit bigfloat closest to @racket[x],
under the current @racket[bf-rounding-mode].
A common pattern to compute bigfloats in higher precision is
@interaction[#:eval untyped-eval
(bf-precision 64)
(eval:alts
(bfcopy
(parameterize ([bf-precision (+ (bf-precision) 10)])
(bf/ (bf+ 1.bf (bfsqrt 5.bf)) 2.bf)))
(eval:result @racketresultfont{(bf #e1.61803398874989484821)}))]
This example computes the golden ratio (@racket[phi.bf]) with 10 bits more than requested,
to make up for triple rounding error.
}
@deftogether[(@defproc[(bigfloat->integer [x Bigfloat]) Integer]
@defproc[(bigfloat->rational [x Bigfloat]) Exact-Rational]
@defproc[(bigfloat->real [x Bigfloat]) (U Exact-Rational Flonum)]
@defproc[(bigfloat->flonum [x Bigfloat]) Flonum])]{
Convert bigfloats to integer, exact rational, real and flonum values respectively.
@racket[bigfloat->integer], @racket[bigfloat->rational] and @racket[bigfloat->real] return values
that can be converted exactly back to @racket[x] using @racket[bf]. For the first two, this is done
by raising an error if @racket[x] is not respectively integer or rational. On the other hand,
@racket[bigfloat->real] returns @racket[+inf.0], @racket[-inf.0] or @racket[+nan.0] when @racket[x]
is not a rational bigfloat.
@racket[bigfloat->flonum] rounds @racket[x] to 53 bits precision to fit the value into a flonum,
using the current value of @racket[bf-rounding-mode].
@interaction[#:eval untyped-eval
(bf-precision 64)
(eval:alts
(bigfloat->integer (bf 21/10))
(eval:result
""
""
"bigfloat->integer: contract violation
expected: bfinteger?
given: (bf #e2.09999999999999999991)"))
(eval:alts
(bigfloat->integer (bfround (bf 21/10)))
(eval:result @racketresultfont{2}))
(eval:alts (define x (bf 1/7)) (eval:result ""))
(eval:alts
(bigfloat->flonum x)
(eval:result @racketresultfont{0.14285714285714285}))
(eval:alts
(bigfloat->rational x)
(eval:result @racketresultfont{10540996613548315209/73786976294838206464}))
(eval:alts
(rationalize (bigfloat->rational x) (expt 2 (- (bf-precision))))
(eval:result @racketresultfont{1/7}))
(eval:alts
(bf= x (bf (bigfloat->rational x)))
(eval:result @racketresultfont{#t}))]
@bold{Be careful with exact conversions.} Bigfloats with large exponents may not fit in memory as
integers or exact rationals. Worse, they might fit, but have all your RAM and swap space for lunch.
}
@deftogether[(@defproc[(bigfloat->string [x Bigfloat]) String]
@defproc[(string->bigfloat [s String]) (U Bigfloat False)])]{
Convert a bigfloat @racket[x] to a string @racket[s] and back.
The string returned by @racket[bigfloat->string] includes enough digits that
@racket[string->bigfloat] can reconstruct the bigfloat precisely. In other words,
@racket[string->bigfloat] is a left inverse of @racket[bigfloat->string].
If @racket[s] isn't a well-formed decimal number with an optional exponent part,
@racket[string->bigfloat] returns @racket[#f]. (In contrast, @racket[(bf s)] raises an error.)
@examples[#:eval untyped-eval
(bf-precision 64)
(eval:alts
(bigfloat->string (bf 4))
(eval:result @racketresultfont{"4"}))
(eval:alts
(bigfloat->string (bf #e0.0001))
(eval:result @racketresultfont{"1.00000000000000000001e-4"}))
(eval:alts
(string->bigfloat "0.14285714285714285714")
(eval:result @racketresultfont{(bf #e0.142857142857142857141)}))
(eval:alts
(string->bigfloat "square root of two")
(eval:result @racketresultfont{#f}))
(eval:alts
(string->bigfloat (bigfloat->string pi.bf))
(eval:result @racketresultfont{(bf #e3.14159265358979323851)}))
(eval:alts
pi.bf
(eval:result @racketresultfont{(bf #e3.14159265358979323851)}))]
}
@deftogether[(@defproc[(bftruncate [x Bigfloat]) Bigfloat]
@defproc[(bffloor [x Bigfloat]) Bigfloat]
@defproc[(bfceiling [x Bigfloat]) Bigfloat]
@defproc[(bfround [x Bigfloat]) Bigfloat])]{
Like @racket[truncate], @racket[floor], @racket[ceiling] and @racket[round], but
for bigfloats.
Rounding is to the nearest integer, with ties broken by rounding to even.
@examples[#:eval untyped-eval
(eval:alts (bfround (bf 1.5)) (eval:result @racketresultfont{(bf 2)}))
(eval:alts (bfround (bf 2.5)) (eval:result @racketresultfont{(bf 2)}))
(eval:alts (bfround (bf -1.5)) (eval:result @racketresultfont{(bf -2)}))
(eval:alts (bfround (bf -2.5)) (eval:result @racketresultfont{(bf -2)}))]
}
@defproc[(bffrac [x Bigfloat]) Bigfloat]{
Returns the fractional part of @racket[x], with the same sign as @racket[x].
}
@defproc[(bfrint [x Bigfloat]) Bigfloat]{
Rounds @racket[x] to the nearest integer bigfloat, in the direction specified by
@racket[(bf-rounding-mode)].
}
@section[#:tag "constants"]{Bigfloat Constants}
Most bigfloat ``constants'' are actually identifier macros that expand to the application
of a zero-argument function. This allows, for example, @racket[pi.bf] to depend on the
current value of @racket[bf-precision], and allows all of them to be constructed lazily.
Most constants are memoized, possibly at multiple precisions.
@deftogether[(@defthing[pi.bf Bigfloat]
@defthing[phi.bf Bigfloat]
@defthing[gamma.bf Bigfloat]
@defthing[catalan.bf Bigfloat]
@defthing[log2.bf Bigfloat])]{
Approximations of π, φ, γ, G and log(2).
@examples[#:eval
untyped-eval
(bf-precision 10)
(eval:alts pi.bf (eval:result @racketresultfont{(bf #e3.1406)}))
(bf-precision 179)
(eval:alts
pi.bf
(eval:result
@racketresultfont{(bf #e3.141592653589793238462643383279502884197169399375105819)}))
(eval:alts
phi.bf
(eval:result
@racketresultfont{bf #e1.618033988749894848204586834365638117720309179805762863)}))
(eval:alts
gamma.bf
(eval:result
@racketresultfont{(bf #e0.5772156649015328606065120900824024310421593359399235988)}))
(eval:alts
catalan.bf
(eval:result
@racketresultfont{(bf #e0.9159655941772190150546035149323841107741493742816721343)}))
(eval:alts
log2.bf
(eval:result
@racketresultfont{(bf #e0.6931471805599453094172321214581765680755001343602552545)}))]
}
@deftogether[(@defthing[-inf.bf Bigfloat]
@defthing[-max.bf Bigfloat]
@defthing[-min.bf Bigfloat]
@defthing[-0.bf Bigfloat]
@defthing[0.bf Bigfloat]
@defthing[+min.bf Bigfloat]
@defthing[+max.bf Bigfloat]
@defthing[+inf.bf Bigfloat]
@defthing[+nan.bf Bigfloat]
@defthing[epsilon.bf Bigfloat])]{
Bigfloat constants corresponding to
@racket[-inf.0], @racket[-max.0] @racket[-min.0], @racket[-0.0],
@racket[0.0], @racket[+min.0], @racket[+max.0], @racket[+inf.0],
@racket[+nan.0] and @racket[epsilon.0].
The constants @racket[-inf.bf], @racket[-0.bf], @racket[0.bf], @racket[+inf.bf],
and @racket[+nan.bf] have fixed precision.
}
@deftogether[(@defthing[-10.bf Bigfloat]
@defthing[-9.bf Bigfloat]
@defthing[-8.bf Bigfloat]
@defthing[-7.bf Bigfloat]
@defthing[-6.bf Bigfloat]
@defthing[-5.bf Bigfloat]
@defthing[-4.bf Bigfloat]
@defthing[-3.bf Bigfloat]
@defthing[-2.bf Bigfloat]
@defthing[-1.bf Bigfloat]
@defthing[1.bf Bigfloat]
@defthing[2.bf Bigfloat]
@defthing[3.bf Bigfloat]
@defthing[4.bf Bigfloat]
@defthing[5.bf Bigfloat]
@defthing[6.bf Bigfloat]
@defthing[7.bf Bigfloat]
@defthing[8.bf Bigfloat]
@defthing[9.bf Bigfloat]
@defthing[10.bf Bigfloat])]{
More fixed-precision bigfloat constants.
}
@section[#:tag "predicates"]{Bigfloat Predicates}
@deftogether[(@defproc[(bfzero? [x Bigfloat]) Boolean]
@defproc[(bfpositive? [x Bigfloat]) Boolean]
@defproc[(bfnegative? [x Bigfloat]) Boolean]
@defproc[(bfinteger? [x Bigfloat]) Boolean]
@defproc[(bfeven? [x Bigfloat]) Boolean]
@defproc[(bfodd? [x Bigfloat]) Boolean]
@defproc[(bfrational? [x Bigfloat]) Boolean]
@defproc[(bfinfinite? [x Bigfloat]) Boolean]
@defproc[(bfnan? [x Bigfloat]) Boolean])]{
Unary predicates corresponding to @racket[zero?], @racket[positive?],
@racket[negative?], @racket[integer?], @racket[even?], @racket[odd?],
@racket[rational?], @racket[infinite?] and @racket[nan?].
}
@deftogether[(@defproc[(bf= [x Bigfloat] [y Bigfloat]) Boolean]
@defproc[(bf> [x Bigfloat] [y Bigfloat]) Boolean]
@defproc[(bf< [x Bigfloat] [y Bigfloat]) Boolean]
@defproc[(bf>= [x Bigfloat] [y Bigfloat]) Boolean]
@defproc[(bf<= [x Bigfloat] [y Bigfloat]) Boolean])]{
Standard comparison functions. As is usual, infinities are either greater or less
than any other bigfloat, and every comparison returns @racket[#f] when either argument
is @racket[+nan.bf].
}
@section[#:tag "ops"]{Bigfloat Operations}
@deftogether[(@defproc[(bfmax [x Bigfloat] ...) Bigfloat]
@defproc[(bfmin [x Bigfloat] ...) Bigfloat])]{
Return the maximum and minimum of their arguments, respectively.
When given no arguments, @racket[bfmin] returns @racket[+inf.bf], and
@racket[bfmax] returns @racket[-inf.bf].
}
@deftogether[(@defproc[(bf+ [x Bigfloat] ...) Bigfloat]
@defproc[(bf* [x Bigfloat] ...) Bigfloat]
@defproc[(bf- [x Bigfloat] [y Bigfloat] ...) Bigfloat]
@defproc[(bf/ [x Bigfloat] [y Bigfloat] ...) Bigfloat]
@defproc[(bfsqr [x Bigfloat]) Bigfloat]
@defproc[(bfabs [x Bigfloat]) Bigfloat]
@defproc[(bfsgn [x Bigfloat]) Bigfloat])]{
Standard arithmetic functions, corresponding to @racket[+], @racket[*],
@racket[-], @racket[/], @racket[sqr], @racket[abs] and @racket[sgn].
When @racket[bf+] and @racket[bf-] are given more than two arguments, they compute
the answers in a way that incurs rounding error only once.
}
@deftogether[(@defproc[(bfsqrt [x Bigfloat]) Bigfloat]
@defproc[(bf1/sqrt [x Bigfloat]) Bigfloat]
@defproc[(bfcbrt [x Bigfloat]) Bigfloat])]{
Return the square root, @italic{reciprocal} square root, and cube root of @racket[x].
}
@defproc[(bfroot [x Bigfloat] [n Integer]) Bigfloat]{
Returns the @racket[n]th root of @racket[x]. @racket[n] must be a nonnegative fixnum.
}
@defproc[(bfhypot [x Bigfloat] [y Bigfloat]) Bigfloat]{
Computes @racket[(bfsqrt (bf+ (bfsqr x) (bfsqr y)))] without uncessary overflow,
incurring rounding error only once. See @racket[flhypot] for an example using flonums.
}
@deftogether[(@defproc[(bflog [x Bigfloat]) Bigfloat]
@defproc[(bflog2 [x Bigfloat]) Bigfloat]
@defproc[(bflog10 [x Bigfloat]) Bigfloat])]{
Return the log of @racket[x] in base @italic{e}, 2 and 10.
}
@deftogether[(@defproc[(bfexp [x Bigfloat]) Bigfloat]
@defproc[(bfexp2 [x Bigfloat]) Bigfloat]
@defproc[(bfexp10 [x Bigfloat]) Bigfloat])]{
Return the exponential of @racket[x] in base @italic{e}, 2 and 10.
}
@deftogether[(@defproc[(bflog1p [x Bigfloat]) Bigfloat]
@defproc[(bfexpm1 [x Bigfloat]) Bigfloat])]{
Like @racket[(bflog (bf+ 1.bf x))] and @racket[(bf- (bfexp x) 1.bf)], but correct
when @racket[x] is near zero. See @racket[fllog1p] for motivation and examples.
}
@defproc[(bfexpt [x Bigfloat] [y Bigfloat]) Bigfloat]{
Computes @racket[x]@superscript{@racket[y]}. See @racket[flexpt] and @racket[expt].
}
@deftogether[(@defproc[(bfsin [x Bigfloat]) Bigfloat]
@defproc[(bfcos [x Bigfloat]) Bigfloat]
@defproc[(bftan [x Bigfloat]) Bigfloat]
@defproc[(bfasin [x Bigfloat]) Bigfloat]
@defproc[(bfacos [x Bigfloat]) Bigfloat]
@defproc[(bfatan [x Bigfloat]) Bigfloat]
@defproc[(bfatan2 [x Bigfloat] [y Bigfloat]) Bigfloat])]{
Standard trigonometric functions and their inverses.
}
@deftogether[(@defproc[(bfsinh [x Bigfloat]) Bigfloat]
@defproc[(bfcosh [x Bigfloat]) Bigfloat]
@defproc[(bftanh [x Bigfloat]) Bigfloat]
@defproc[(bfasinh [x Bigfloat]) Bigfloat]
@defproc[(bfacosh [x Bigfloat]) Bigfloat]
@defproc[(bfatanh [x Bigfloat]) Bigfloat])]{
Standard hyperbolic functions and their inverses.
}
@deftogether[(@defproc[(bfsec [x Bigfloat]) Bigfloat]
@defproc[(bfcsc [x Bigfloat]) Bigfloat]
@defproc[(bfcot [x Bigfloat]) Bigfloat])]{
Standard @italic{reciprocal} trigonometric functions. MPFR does not implement their inverses.
}
@deftogether[(@defproc[(bfsech [x Bigfloat]) Bigfloat]
@defproc[(bfcsch [x Bigfloat]) Bigfloat]
@defproc[(bfcoth [x Bigfloat]) Bigfloat])]{
Standard @italic{reciprocal} hyperbolic functions. MPFR does not implement their inverses.
}
@defproc[(bfsin+cos [x Bigfloat]) (Values Bigfloat Bigfloat)]{
Simultaneously computes the sine and cosine of @racket[x].
}
@defproc[(bfsinh+cosh [x Bigfloat]) (Values Bigfloat Bigfloat)]{
Simultaneously computes the hyperbolic sine and cosine of @racket[x].
}
@defproc[(bffactorial [x Integer]) Bigfloat]{
Returns the factorial of @racket[x].
}
@defproc[(bfgamma [x Bigfloat]) Bigfloat]{
Computes the @hyperlink["http://en.wikipedia.org/wiki/Gamma_function"]{gamma function},
a generalization of the factorial function.
}
@deftogether[(@defproc[(bflog-gamma [x Bigfloat]) Bigfloat]
@defproc[(bflog-gamma/sign [x Bigfloat]) (Values Bigfloat (U -1 1))])]{
Computes the @hyperlink["http://mathworld.wolfram.com/LogGammaFunction.html"]{log-gamma function},
or the log of the absolute value of the gamma function. @racket[bflog-gamma/sign] additionally
returns the sign of @racket[(bfgamma x)].
}
@defproc[(bfpsi0 [x Bigfloat]) Bigfloat]{
Computes the @hyperlink["http://en.wikipedia.org/wiki/Digamma_function"]{digamma function},
the logarithmic derivative of the gamma function.
}
@defproc[(bfeint [x Bigfloat]) Bigfloat]{
Returns the @hyperlink["http://en.wikipedia.org/wiki/Exponential_integral"]{exponential integral}
of @racket[x].
}
@defproc[(bfli2 [x Bigfloat]) Bigfloat]{
Returns the dilogarithm of @racket[x], or the
@hyperlink["http://en.wikipedia.org/wiki/Polylogarithm"]{polylogarithm} of order 2.
}
@defproc[(bfzeta [x Bigfloat]) Bigfloat]{
Computes the @hyperlink["http://en.wikipedia.org/wiki/Riemann_zeta_function"]{Riemann zeta function}.
}
@deftogether[(@defproc[(bferf [x Bigfloat]) Bigfloat]
@defproc[(bferfc [x Bigfloat]) Bigfloat])]{
Compute the @hyperlink["http://en.wikipedia.org/wiki/Error_function"]{error function and
complementary error function}, respectively.
}
@deftogether[(@defproc[(bfbesj0 [x Bigfloat]) Bigfloat]
@defproc[(bfbesj1 [x Bigfloat]) Bigfloat]
@defproc[(bfbesj [n Integer] [x Bigfloat]) Bigfloat]
@defproc[(bfbesy0 [x Bigfloat]) Bigfloat]
@defproc[(bfbesy1 [x Bigfloat]) Bigfloat]
@defproc[(bfbesy [n Integer] [x Bigfloat]) Bigfloat])]{
These compute @hyperlink["http://en.wikipedia.org/wiki/Bessel_function"]{Bessel functions}.
A ``@racket[j]'' in the name indicates that a function computes a Bessel function of the
first kind. A ``@racket[y]'' indicates the second kind.
The ``@racket[j]'' or ``@racket[y]'' is followed by the @italic{order}: zero, one, or
@racket[n] (user-specified).
}
@defproc[(bfagm [x Bigfloat] [y Bigfloat]) bigfloat]{
Returns the
@hyperlink["http://en.wikipedia.org/wiki/Arithmetic-geometric_mean"]{arithmetic-geometric mean}
of @racket[x] and @racket[y]. Typically, this isn't directly useful, but it's used in some
asymptotically fast algorithms such as the one that computes @racket[bflog].
}
@section[#:tag "misc"]{Low-level Bigfloat Functions}
@deftogether[(@defproc[(bigfloat->ordinal [x Bigfloat]) Integer]
@defproc[(ordinal->bigfloat [n Integer]) Bigfloat]
@defproc[(bigfloats-between [x Bigfloat] [y Bigfloat]) Integer]
@defproc[(bfstep [x Bigfloat] [n Integer]) Bigfloat]
@defproc[(bfnext [x Bigfloat]) Bigfloat]
@defproc[(bfprev [x Bigfloat]) Bigfloat])]{
Like @racket[flonum->ordinal], @racket[ordinal->flonum], @racket[flonums-between],
@racket[flstep], @racket[flnext] and @racket[flprev], but for bigfloats.
The major difference is that these operate using @racket[(bf-precision)] bits.
Additionally, unlike other bigfloat functions, all of these convert their bigfloat arguments
to @racket[(bf-precision)] bits.
}
@defproc[(bfshift [x Bigfloat] [n Integer]) Bigfloat]{
Like @racket[arithmetic-shift], but for bigfloats. More precisely, this returns
@racket[(bf* x (bfexpt (bf 2) (bf n)))], but is much faster.
}
@defproc[(bfcanonicalize [x Bigfloat]) Bigfloat]{
@margin-note*{Bigfloats are canonicalized before hashing, to ensure that equality
implies an equal hash.}
If @racket[x] is nonzero and rational, returns a new bigfloat with no more bits of
precision than are necessary to encode @racket[x] exactly, by removing all low-order
zeros from the significand and adjusting the exponent.
For zero or non-rational @racket[x], returns @racket[-inf.bf], @racket[-0.bf],
@racket[0.bf], @racket[+inf.bf], or @racket[+nan.bf], depending on the value of @racket[x].
Two nonzero, rational bigfloats are @racket[equal?] if and only if their canonicalized
significands and exponents are equal. Two zero or non-rational bigfloats are @racket[equal?]
if and only if their canonicalizations are @racket[eq?].
Canonicalizing bigfloats won't change answers computed from them.
@examples[#:eval untyped-eval
(bf-precision 64)
(eval:alts (define x (bf 1 -2)) (eval:result ""))
(eval:alts x (eval:result @racketresultfont{(bf #e0.25)}))
(eval:alts (bfcanonicalize x)
(eval:result @racketresultfont{(bf #e0.25)}))
(eval:alts (bigfloat-precision x)
(eval:result @racketresultfont{64}))
(eval:alts (bigfloat-precision (bfcanonicalize x))
(eval:result @racketresultfont{2}))]
}
@section[#:tag "loading"]{Loading the MPFR Library}
The @racketmodname[math/bigfloat] library depends directly on one library: MPFR, which on the filesystem is
named something like @filepath{libmpfr.so}, but with a platform-specific suffix.
MPFR itself depends on @hyperlink["http://gmplib.org/"]{GMP}, the
GNU Multiple Precision Arithmetic Library, which on the filesystem is named @filepath{libgmp.so}.
If @racket[(mpfr-available?)] is @racket[#t], both of these libraries have been loaded
by the Racket runtime, and everything in @racketmodname[math/bigfloat] should work.
(If something doesn't, it's likely an error in the foreign function interface. In that
case, please email the author of this library or submit a bug report.)
If @racket[(mpfr-available?)] is @racket[#f], one of these libraries can't be loaded. The
most common reason is that one or both needs to be installed. Another possibility is that
both are installed, but one is not in the operating system's search path. In this case,
see @racket[set-mpfr-lib-dirs!].
@defproc[(mpfr-available?) Boolean]{
Returns @racket[#t] when both GMP and MPFR are available; @racket[#f] otherwise.
}
@(close-eval untyped-eval)