抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

开发思路

生成随机数方法有很多种,我觉得比较好的一种思路就是先计算剩余金额的平均值, 然后根据剩余金额的平局值获取最大值或者最小值距离平均值之间的一个正太分布值(范围内的随机值,保证在最大值和最小值之间 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php

class RedPacket
{
/**
* @param float $rmb 红包总金额
* @param int $num 红包合适
* @param int $kind int 0 随机 1平均
* @param int $max 最大红包金额
* @return array|bool
*/
public static function create($rmb, $num, $kind = 0, $max = 0)
{
if ($num < 2) $kind = 1;
$min = 0.01;//最小金额
$packets = [];
switch ($kind) {
case 1://固定金额红包
$money = sprintf("%.2f", $rmb / $num);
for ($i = 1; $i <= $num; $i++) {
$packets[] = $money;
}
return $packets;
default://随机红包
if ($min * $num > $rmb) {
return false;
}
if ($num * $max < $rmb || $max + $num * $min > $rmb) {//验证最大红包金额是否正确
$max = $rmb / 3;
}

while ($num >= 1) {
$num--;
$kMin = max($min, $rmb - $num * $max);
$kMax = min($max, $rmb - $num * $min);
$kAvg = $rmb / ($num + 1);
//获取最大值和最小值的距离之间的最小值
$kDis = min($kAvg - $kMin, $kMax - $kAvg);
//获取0到1之间的随机数与距离最小值相乘得出浮动区间,这使得浮动区间不会超出范围
$r = ((float)(rand(1, 10000) / 10000) - 0.5) * $kDis * 2;
$k = sprintf("%.2f", $kAvg + $r);
$rmb -= $k;
$packets[] = $k;
}

shuffle($packets);
return $packets;
}
}
}