You need to enable JavaScript to run this app. PostgreSQL中如何生成两个DOUBLE PRECISION数值间的不越界随机数
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中如何生成两个DOUBLE PRECISION数值间的不越界随机数

问题根因
  • PostgreSQL 内置random()函数的返回值范围为左闭右开的[0, 1),取值永远不会等于1。
  • 你当前公式中额外加上的+1是整数随机数场景的专属偏移逻辑:仅当需要生成离散整数的连续区间时,才需要用这个偏移把区间拉满覆盖所有整数。
  • 对于DOUBLE PRECISION浮点数场景,这个+1会直接把生成区间的总长度额外拉大1,最终导致返回值超过预设的high上限。

举个直观的例子:当你设置low=0、high=1时,原公式的计算逻辑为random() * (1 - 0 + 1) + 0 = random() * 2,由于random()最大趋近于1,返回值最大会趋近于2,完全超出预设范围。

修正实现

根据业务需要的区间边界,对应选择即可:

场景1:生成左闭右开区间[low, high)的随机数(浮点数随机的通用标准实现)

直接删除公式中多余的+1即可:

CREATE OR REPLACE FUNCTION random_between(low DOUBLE PRECISION, high DOUBLE PRECISION)
    RETURNS DOUBLE PRECISION AS
$$
BEGIN
    RETURN random() * (high - low) + low;
END;
$$ LANGUAGE plpgsql STRICT;

原函数保留的STRICT属性逻辑正常,无需调整,入参为NULL时会直接返回NULL,符合空值处理的预期。该实现的返回值严格落在[low, high)范围内,不会越界。

场景2:需要覆盖high边界的闭区间需求

由于random()本身无法取到1,无法靠线性映射直接生成等于high的浮点数;且双精度浮点数的精度特性下,刚好命中连续区间端点的概率极低,多数业务场景下左闭右开的结果已经完全满足需求。如果确实需要强制覆盖high边界,可以补充边界钳制逻辑:

CREATE OR REPLACE FUNCTION random_between(low DOUBLE PRECISION, high DOUBLE PRECISION)
    RETURNS DOUBLE PRECISION AS
$$
DECLARE
    res DOUBLE PRECISION;
BEGIN
    res := random() * (high - low) + low;
    -- 钳制数值不超出上下限
    RETURN LEAST(GREATEST(res, low), high);
END;
$$ LANGUAGE plpgsql STRICT;

注意:上述钳制逻辑会人为小幅提升high边界值的出现概率,仅在明确需要包含边界的场景下使用。


内容的提问来源于stack exchange,提问作者A.A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.05 01:15:04