php 随机红包数生成

无论哪种实现方式,随机红包都要遵守几个核心约束(这是和单纯随机数最大的区别):

  1. 总金额固定(比如 100 元分 10 个红包);
  2. 每个红包金额非空(至少 0.01 元,避免分到 0);
  3. 金额随机且符合 "拼手气" 特性(有人多有人少,而非平均);
  4. 所有红包金额之和严格等于总金额。
php 复制代码
/**
 * 随机分配红包金额.
 *
 * @param float|string $totalMoney 总金额(元)
 * @param int          $totalTimes 总次数
 * @param float|string $minMoney   单次最小值(元)
 * @param float|string $maxMoney   单次最大值(元)
 *
 * @return array|false 包含每次红包金额的数组(保留两位小数)|false 参数错误时返回false
 */
function random_red_packet($totalMoney, $totalTimes, $minMoney, $maxMoney)
{
    // 转换为分进行计算,避免浮点数精度问题
    $totalMoneyCent = (int) bcmul($totalMoney, 100);
    $minMoneyCent = (int) bcmul($minMoney, 100);
    $maxMoneyCent = (int) bcmul($maxMoney, 100);

    // 参数合法性校验
    if (
        $totalTimes <= 0
        || $minMoneyCent <= 0
        || $maxMoneyCent < $minMoneyCent
        || $totalMoneyCent < $totalTimes * $minMoneyCent // 总金额不足以分配最小值
        || $totalMoneyCent > $totalTimes * $maxMoneyCent    // 总金额超过最大值总和
    ) {
        return false;
    }

    $redPackets = [];
    $remainingCent = $totalMoneyCent;
    $remainingTimes = $totalTimes;

    for ($i = 0; $i < $totalTimes; ++$i) {
        // 最后一次直接分配剩余金额
        if (1 == $remainingTimes) {
            $currentCent = $remainingCent;
        } else {
            // 计算当前可分配的最大金额:不超过单红包最大值,且剩余次数能满足最小值
            $maxCurrentCent = min(
                $maxMoneyCent,
                $remainingCent - ($remainingTimes - 1) * $minMoneyCent
            );
            // 随机生成当前红包金额(在最小值和最大可分配金额之间)
            $currentCent = mt_rand($minMoneyCent, $maxCurrentCent);
        }

        // 转换为元并保留两位小数
        $redPackets[] = bcdiv($currentCent, 100, 2);

        // 更新剩余金额和次数
        $remainingCent = bcsub($remainingCent, $currentCent, 2);
        --$remainingTimes;
    }

    // 打乱数组(可选,模拟随机顺序)
    shuffle($redPackets);

    return $redPackets;
}
相关推荐
程序员林北北2 小时前
【前端进阶之旅】JavaScript 一些常用的简写技巧
开发语言·前端·javascript
gAlAxy...3 小时前
MyBatis-Plus 核心 CRUD 操作全解析:BaseMapper 与通用 Service 实战
java·开发语言·mybatis
开开心心就好3 小时前
一键加密隐藏视频,专属格式播放工具
java·linux·开发语言·网络·人工智能·macos
CUC-MenG3 小时前
Codeforces Round 1079 (Div. 2)A,B,C,D,E1,E2,F个人题解
c语言·开发语言·数学·算法
阿里嘎多学长3 小时前
2026-02-07 GitHub 热点项目精选
开发语言·程序员·github·代码托管
Anastasiozzzz4 小时前
Java异步编程:CompletableFuture从入门到底层实现
java·开发语言
九.九4 小时前
高性能算子库 ops-nn 的底层架构:从调度到指令的极致优化
开发语言
比奇堡派星星4 小时前
sed命令
linux·运维·服务器·开发语言
船神丿男人4 小时前
C++:STL string(一)
开发语言·c++