使用.Machine$double.xmax作为边界的runif函数

9

我希望生成一个随机实数(我猜测是有理数)。

为了做到这一点,我想使用runif(1, min = m, max = M),我的想法是尽可能将m; M(绝对值)设置得大一些,以便让区间尽可能地大。这就带来了我的问题:

M <- .Machine$double.xmax
m <- -M
runif(1, m, M)
## which returns
[1] Inf

为什么它没有返回数字?所选的时间间隔是否太大了?
PS
> .Machine$double.xmax
[1] 1.797693e+308

6
有趣的问题。一种解决方法是 M * runif(1, -1, 1) - mt1022
7
这是runif函数的源代码:https://github.com/wch/r-source/blob/af7f52f70101960861e5d995d3a4bec010bc89e6/src/nmath/runif.c。看起来,`M`是最大的双精度浮点数,而`M - (-M)将大于最大的双精度浮点数,因此b-a将会是无穷大,这可能解释了为什么a + (b-a)*u`是无穷大。 - mt1022
1个回答

1

正如mt1022所暗示的那样,原因在于runifC源代码

double runif(double a, double b)
{
    if (!R_FINITE(a) || !R_FINITE(b) || b < a)  ML_ERR_return_NAN;

    if (a == b)
    return a;
    else {
    double u;
    /* This is true of all builtin generators, but protect against
       user-supplied ones */
    do {u = unif_rand();} while (u <= 0 || u >= 1);
    return a + (b - a) * u;
    }
}

return参数中,您可以看到公式a + (b - a) * u,该公式将[0,1]生成的随机值均匀转换为用户提供的区间[a,b]。在您的情况下,它将是-M + (M + M) * u。因此,在M+M等于1.79E308+1.79E308的情况下,会生成Inf。即finite + Inf * finite = Inf
M + (M - m) * runif(1, 0, 1)
# Inf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接