fr_ld_exp: Base-2 Representation and Multiplication of Numbers

fr_ld_expR 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 double) vector.

f

numeric fraction (vector), in [0.5, 1).

E

integer valued, exponent of 2, i.e., typically in (-1024-50):1024, otherwise the result will underflow to 0 or overflow to +/- Inf.

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])
})

DPQ documentation built on Nov. 3, 2024, 3 a.m.