fr_ld_exp {DPQ} | R Documentation |
Base-2 Representation and Multiplication of Numbers
Description
Both are R versions of C99 (and POSIX) standard C (and C++) mathlib functions of the same name.
frexp(x)
computes base-2 exponent e
and “mantissa”,
or fraction r
, such that x = r * 2^e
, where r \in
[0.5, 1)
(unless when x
is in c(0, -Inf, Inf, NaN)
where r == x
and e
is 0),
and e
is integer valued.
ldexp(f, E)
is the inverse of frexp()
: Given
fraction or mantissa f
and integer exponent E
, it returns
x = f * 2^E
.
Viewed differently, it's the fastest way to multiply or divide (double
precision) numbers with 2^E
.
Usage
frexp(x)
ldexp(f, E)
Arguments
x |
numeric (coerced to |
f |
numeric fraction (vector), in |
E |
integer valued, exponent of |
Value
frexp
returns a list
with named components r
(of type double
) and e
(of type integer
).
Author(s)
Martin Maechler
References
On unix-alikes, typically man frexp
and man ldexp
See Also
Vaguely relatedly, log1mexp()
, lsum
, logspace.add
.
Examples
set.seed(47)
x <- c(0, 2^(-3:3), (-1:1)/0,
rlnorm(2^12, 10, 20) * sample(c(-1,1), 512, replace=TRUE))
head(x, 12)
which(!(iF <- is.finite(x))) # 9 10 11
rF <- frexp(x)
sapply(rF, summary) # (nice only when x had no NA's ..)
data.frame(x=x[!iF], lapply(rF, `[`, !iF))
## by C.99/POSIX 'r' should be the same as 'x' for these,
## x r e
## 1 -Inf -Inf 0
## 2 NaN NaN 0
## 3 Inf Inf 0
## but on Windows, we've seen 3 NA's :
ar <- abs(rF$r)
ldx <- with(rF, ldexp(r, e))
stopifnot(exprs = {
0.5 <= ar[iF & x != 0]
ar[iF] < 1
is.integer(rF$e)
all.equal(x[iF], ldx[iF], tol= 4*.Machine$double.eps)
## but actually, they should even be identical, well at least when finite
identical(x[iF], ldx[iF])
})