最近做红包业务,查了下网上的红包算法资料,整理出来一份自己记录下
领取的逻辑中心思想逻辑是:
每次领取的金额在 0.01和(剩余平均值*2)之间
import java.util.Random;
public class RedPackageUtil {
/**
* remainSize 剩余的红包数量
* remainMoney 剩余的钱
*/
public static double getRandomMoney(Integer remainSize, Double remainMoney) {
if (remainSize == 1) {
double last = (double) Math.round(remainMoney * 100) / 100;
System.out.println("最后一次抢到" + last + ", 剩余红包数量:" + remainSize-- + ", 剩余金额:" + (remainMoney - last));
return last;
}
Random r = new Random();
double min = 0.01; //
double max = remainMoney / remainSize * 2;
double money = r.nextDouble() * max;
money = money <= min ? 0.01 : money;
money = Math.floor(money * 100) / 100;
remainSize--;
remainMoney -= money;
remainMoney = Math.floor(remainMoney * 100) / 100;
System.out.println("本次抢到" + money + ", 剩余红包数量:" + remainSize + ", 剩余金额:" + remainMoney);
getRandomMoney(remainSize, remainMoney);
return money;
}
public static void main(String[] args) {
RedPackageUtil.getRandomMoney(10, 100d);
}
}
补一个BigDecimal版的
/**
* @param remainSize 剩余的红包数量
* @param remainMoney 剩余的钱
* @return
*/
public static BigDecimal getRandomMoneyBigDecimal(Integer remainSize, BigDecimal remainMoney) {
if (remainSize == 1) {
BigDecimal last = remainMoney.setScale(2, BigDecimal.ROUND_DOWN);
System.out.println("BigDecimal最后一次抢到" + last + ", 剩余红包数量:" + remainSize-- + ", 剩余金额:" + remainMoney.subtract(last));
return last;
}
BigDecimal random = BigDecimal.valueOf(Math.random());
BigDecimal min = BigDecimal.valueOf(0.01);
BigDecimal halfRemainSize = BigDecimal.valueOf(remainSize).divide(new BigDecimal(2), BigDecimal.ROUND_UP);
BigDecimal max1 = remainMoney.divide(halfRemainSize, BigDecimal.ROUND_DOWN);
BigDecimal minRemainAmount = min.multiply(BigDecimal.valueOf(remainSize - 1)).setScale(2, BigDecimal.ROUND_DOWN);
BigDecimal max2 = remainMoney.subtract(minRemainAmount);
BigDecimal max = (max1.compareTo(max2) < 0) ? max1 : max2;
BigDecimal money = random.multiply(max).setScale(2, BigDecimal.ROUND_DOWN);
money = money.compareTo(min) < 0 ? min: money;
remainSize--;
remainMoney = remainMoney.subtract(money).setScale(2, BigDecimal.ROUND_DOWN);
System.out.println("BigDecimal本次抢到" + money + ", 剩余红包数量:" + remainSize + ", 剩余金额:" + remainMoney);
getRandomMoneyBigDecimal(remainSize, remainMoney);
return money;
}
public static void main(String[] args) {
// RedPackageUtil.getRandomMoney(25, 50d);
RedPackageUtil.getRandomMoneyBigDecimal(25, new BigDecimal(50));
}
大家可以复制自己执行一下试试,算法基本都是参考网上资料的,有问题欢迎指正