购物网站做兼职,泉州人才网,网站建设企业 熊掌号,wordpress 更换中文无论哪种实现方式#xff0c;随机红包都要遵守几个核心约束#xff08;这是和单纯随机数最大的区别#xff09;#xff1a;总金额固定#xff08;比如 100 元分 10 个红包#xff09;#xff1b;每个红包金额非空#xff08;至少 0.01 元#xff0c;避免分到 0#x…无论哪种实现方式随机红包都要遵守几个核心约束这是和单纯随机数最大的区别总金额固定比如 100 元分 10 个红包每个红包金额非空至少 0.01 元避免分到 0金额随机且符合 “拼手气” 特性有人多有人少而非平均所有红包金额之和严格等于总金额。/** * 随机分配红包金额. * * 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; }