发红包

发红包算是比较具有中国特色,而且也算是常见的营销活动。

代码:

    public function generateMoney($total, int $people, int $iv = 5)
    {
        $sum = 0;
        $data = [];
        for ($i = 0; $i < $people; $i++) {
            $prob = mt_rand(1, $people * $iv);
            $data[] = $prob;
            $sum += $prob;
        }

        $count = 1;
        $last = 0;
        foreach ($data as $item) {
            $money = bcdiv(bcmul($total, $item, 2), $sum, 2);
            if ($count === $people) {
                $money = bcsub($total, $last, 2);
            }
            yield $money;
            $count += 1;
            $last = bcadd($last, $money, 2);
        }
    }

iv 参数是设置扩大随机的范围,当参与人数比较小,比如 2 人,也具有一定的随机性,而不是产生平分的状况。

这里需要注意的是金额为保留两位小数,即精确到分,以“元”为单位,由于精度的问题,所以最后一位需要圆整,即总额减去之前的总和。

代码用到了浮点数运算,所以使用了 Bcmath 扩展, 也可以将数值乘以 100,以“分”为单位来做运算。

使用:

$result = iterator_to_array($this->generateMoney(120, 4));