racket/collects/scribblings/reference/flonums.scrbl
Noel Welsh cfa7b727f4 Fix some errors with in-vector and derived forms:
- Range checking was inconsistent between the sequence and macro forms
- The macro form could crash due to unsafe vector refs

Fixes involved refactoring the range checks so they are shared between both versions, and changing the contract slightly so start and stop are checked before the sequence runs. This allows unsafe vector refs and earlier error notifications at the cost making some valid programs (e.g. those using some condition to stop a comprehension hitting an invalid index) now be invalid. Only crazy people would rely on the old behaviour, so it isn't a problem in practice.
2010-12-13 13:38:35 +00:00

222 lines
7.5 KiB
Racket

#lang scribble/doc
@(require "mz.ss"
(for-label racket/flonum))
@(define fl-eval (make-base-eval))
@(interaction-eval #:eval fl-eval (require racket/flonum))
@title[#:tag "flonums"]{Flonums}
@defmodule[racket/flonum]
The @racketmodname[racket/flonum] library provides operations like
@racket[fl+] that consume and produce only
@tech{flonums}. Flonum-specific operations provide can better
performance when used consistently, and they are as safe as generic
operations like @racket[+].
@guidealso["fixnums+flonums"]
@; ------------------------------------------------------------------------
@section{Flonum Arithmetic}
@deftogether[(
@defproc[(fl+ [a flonum?] [b flonum?]) flonum?]
@defproc[(fl- [a flonum?] [b flonum?]) flonum?]
@defproc[(fl* [a flonum?] [b flonum?]) flonum?]
@defproc[(fl/ [a flonum?] [b flonum?]) flonum?]
@defproc[(flabs [a flonum?]) flonum?]
)]{
Like @racket[+], @racket[-], @racket[*], @racket[/], and @racket[abs],
but constrained to consume @tech{flonums}. The result is always a
@tech{flonum}.}
@deftogether[(
@defproc[(fl= [a flonum?] [b flonum?]) boolean?]
@defproc[(fl< [a flonum?] [b flonum?]) boolean?]
@defproc[(fl> [a flonum?] [b flonum?]) boolean?]
@defproc[(fl<= [a flonum?] [b flonum?]) boolean?]
@defproc[(fl>= [a flonum?] [b flonum?]) boolean?]
@defproc[(flmin [a flonum?] [b flonum?]) flonum?]
@defproc[(flmax [a flonum?] [b flonum?]) flonum?]
)]{
Like @racket[=], @racket[<], @racket[>], @racket[<=], @racket[>=],
@racket[min], and @racket[max], but constrained to consume
@tech{flonums}.}
@deftogether[(
@defproc[(flround [a flonum?]) flonum?]
@defproc[(flfloor [a flonum?]) flonum?]
@defproc[(flceiling [a flonum?]) flonum?]
@defproc[(fltruncate [a flonum?]) flonum?]
)]{
Like @racket[round], @racket[floor], @racket[ceiling], and
@racket[truncate], but constrained to consume @tech{flonums}.}
@deftogether[(
@defproc[(flsin [a flonum?]) flonum?]
@defproc[(flcos [a flonum?]) flonum?]
@defproc[(fltan [a flonum?]) flonum?]
@defproc[(flasin [a flonum?]) flonum?]
@defproc[(flacos [a flonum?]) flonum?]
@defproc[(flatan [a flonum?]) flonum?]
@defproc[(fllog [a flonum?]) flonum?]
@defproc[(flexp [a flonum?]) flonum?]
@defproc[(flsqrt [a flonum?]) flonum?]
)]{
Like @racket[sin], @racket[cos], @racket[tan], @racket[asin],
@racket[acos], @racket[atan], @racket[log], @racket[exp], and
@racket[flsqrt], but constrained to consume and produce
@tech{flonums}. The result is @racket[+nan.0] when a number outside
the range @racket[-1.0] to @racket[1.0] is given to @racket[flasin] or
@racket[flacos], or when a negative number is given to @racket[fllog]
or @racket[flsqrt].}
@defproc[(->fl [a exact-integer?]) flonum?]{
Like @racket[exact->inexact], but constrained to consume exact
integers, so the result is always a @tech{flonum}.}
@defproc[(fl->exact-integer [a flonum?]) exact-integer?]{
Like @racket[inexact->exact], but constrained to consume an
@tech{integer} @tech{flonum}, so the result is always an exact
integer.}
@deftogether[(
@defproc[(make-flrectangular [a flonum?] [b flonum?])
(and/c complex? inexact? (not/c real?))]
@defproc[(flreal-part [a (and/c complex? inexact? (not/c real?))]) flonum?]
@defproc[(flimag-part [a (and/c complex? inexact? (not/c real?))]) flonum?]
)]{
Like @racket[make-rectangular], @racket[real-part], and
@racket[imag-part], but both parts of the complex number must be
inexact.}
@; ------------------------------------------------------------------------
@section{Flonum Vectors}
A @deftech{flvector} is like a @tech{vector}, but it holds only
inexact real numbers. This representation can be more compact, and
unsafe operations on @tech{flvector}s (see
@racketmodname[racket/unsafe/ops]) can execute more efficiently than
unsafe operations on @tech{vectors} of inexact reals.
An f64vector as provided by @racketmodname[ffi/vector] stores the
same kinds of values as an @tech{flvector}, but with extra
indirections that make f64vectors more convenient for working with
foreign libraries. The lack of indirections make unsafe
@tech{flvector} access more efficient.
Two @tech{flvectors} are @racket[equal?] if they have the same length,
and if the values in corresponding slots of the @tech{flvectors} are
@racket[equal?].
@defproc[(flvector? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a @tech{flvector}, @racket[#f] otherwise.}
@defproc[(flvector [x flonum?] ...) flvector?]{
Creates a @tech{flvector} containing the given inexact real numbers.
@mz-examples[#:eval fl-eval (flvector 2.0 3.0 4.0 5.0)]}
@defproc[(make-flvector [size exact-nonnegative-integer?]
[x flonum? 0.0])
flvector?]{
Creates a @tech{flvector} with @racket[size] elements, where every
slot in the @tech{flvector} is filled with @racket[x].
@mz-examples[#:eval fl-eval (make-flvector 4 3.0)]}
@defproc[(flvector-length [vec flvector?]) exact-nonnegative-integer?]{
Returns the length of @racket[vec] (i.e., the number of slots in the
@tech{flvector}).}
@defproc[(flvector-ref [vec flvector?] [pos exact-nonnegative-integer?])
flonum?]{
Returns the inexact real number in slot @racket[pos] of
@racket[vec]. The first slot is position @racket[0], and the last slot
is one less than @racket[(flvector-length vec)].}
@defproc[(flvector-set! [vec flvector?] [pos exact-nonnegative-integer?]
[x flonum?])
flonum?]{
Sets the inexact real number in slot @racket[pos] of @racket[vec]. The
first slot is position @racket[0], and the last slot is one less than
@racket[(flvector-length vec)].}
@defproc[(flvector-copy [vec flvector?]
[start exact-nonnegative-integer? 0]
[end exact-nonnegative-integer? (vector-length v)])
flvector?]{
Creates a fresh @tech{flvector} of size @racket[(- end start)], with all of the
elements of @racket[vec] from @racket[start] (inclusive) to
@racket[end] (exclusive).}
@defproc[(in-flvector [vec flvector?]
[start exact-nonnegative-integer? 0]
[stop (or/c exact-integer? #f) #f]
[step (and/c exact-integer? (not/c zero?)) 1])
sequence?]{
Returns a sequence equivalent to @racket[vec] when no optional
arguments are supplied.
The optional arguments @racket[start], @racket[stop], and
@racket[step] are as in @racket[in-vector].
A @racket[in-flvector] application can provide better
performance for @tech{flvector} iteration when it appears directly in a @racket[for] clause.
}
@deftogether[(
@defform*[((for/flvector (for-clause ...) body ...)
(for/flvector #:length length-expr (for-clause ...) body ...))]
@defform*[((for*/flvector (for-clause ...) body ...)
(for*/flvector #:length length-expr (for-clause ...) body ...))])]{
Like @scheme[for/vector] or @scheme[for*/vector], but for
@tech{flvector}s.}
@defproc[(shared-flvector [x flonum?] ...) flvector?]{
Creates a @tech{flvector} containing the given inexact real numbers.
When @tech{places} are enabled, the new @tech{flvector} is
allocated in the @tech{shared memory space}.
@mz-examples[#:eval fl-eval (shared-flvector 2.0 3.0 4.0 5.0)]}
@defproc[(make-shared-flvector [size exact-nonnegative-integer?]
[x flonum? 0.0])
flvector?]{
Creates a @tech{flvector} with @racket[size] elements, where every
slot in the @tech{flvector} is filled with @racket[x].
When @tech{places} are enabled, the new @tech{flvector} is
allocated in the @tech{shared memory space}.
@mz-examples[#:eval fl-eval (make-shared-flvector 4 3.0)]}
@; ------------------------------------------------------------
@close-eval[fl-eval]