java 红包规则
java 红包规则
拼手气红包:
规则:最大金额:全部金额/个数*倍数
最小金额:0.01
最后一个红包是全部金额-领取金额
随机分配
package com.utils; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* 红包分发工具类
*
*/
public class CashRedPackUtils {
/**
* 一个红包最少拆分数量
*/
public static final int REDPACK_MIN_QUANTITY = 1;
/**
* 一个红包最多拆分数量
*/
public static final int REDPACK_MAX_QUANTITY = 100;
/**
* 小数位长度
*/
private static final int SCALE = 2;
/**
* 舍弃的小数位处理方式
*/
private static final RoundingMode ROUNDING_MODE = RoundingMode.HALF_EVEN;
/**
* 红包放大倍数
*/
private static final BigDecimal TIMES = new BigDecimal("3");
/**
* 单个红包最小金额
*/
public static final BigDecimal SINGLE_RED_MIN_MONEY = new BigDecimal("0.01");
/**
* 单个红包最大金额
*/
// private static final BigDecimal SINGLE_RED_MAX_MONEY = new BigDecimal("100");
/**
* 递归计算红包金额时连续错误最大值,超过此次数将返回最小值
*/
private static final int ERROR_MAX_NUM = 5;
/**
* 递归计算红包金额连续错误次数初始值
*/
private static final int ERROR_INIT_NUM = 1;
/**
* 计算金额时的小数位,1000代表3位小数
*/
private static final int FRACTION_LENGTH = 1000; /**
* 分发红包
* @param redMoney 红包总金额
* @param num 红包数量
* @return
*/
public static List<BigDecimal> SplitRedPackes(BigDecimal redMoney, int num) {
List<BigDecimal> redInfoList = new ArrayList<>();
// 红包有误
if(num < REDPACK_MIN_QUANTITY || num > REDPACK_MAX_QUANTITY)
return redInfoList; //校验:金额大于0
if(redMoney.compareTo(BigDecimal.ZERO) != 1) {
return redInfoList;
} if(num <= 1) {
redInfoList.add(redMoney);
return redInfoList;
}
Random random = new Random();
for(int i = 0; i < num; i++) {
// System.out.println("\n" + (i+1) + "个红包信息:");
int surplusNum = num - i;//未分配金额红包数量
BigDecimal curRedMoney = fightLuckRedPacked(redMoney, surplusNum, random, ERROR_INIT_NUM);
redInfoList.add(curRedMoney);
redMoney = redMoney.subtract(curRedMoney);
// MandoAssert.notTrue(redMoney.compareTo(BigDecimal.ZERO) == -1, "红包金额有误");
// System.out.println("红包金额:" + curRedMoney + ",剩余:" + redMoney);
}
return redInfoList;
} /**
* 拼手气红包
* @param redMoney 红包金额
* @param num 红包数量
* @param random 随机数生成对象
* @param errorNum 错误测试
* @return 单个红包金额
*/
private static BigDecimal fightLuckRedPacked(BigDecimal redMoney, int num, Random random, int errorNum) {
if(num <= 1) {
return redMoney;
}
if(errorNum > ERROR_MAX_NUM) {
//随机金额产生错误次数超过上限,返回最小值
return SINGLE_RED_MIN_MONEY;
}
//每个红包最大金额 = 剩余总金额 / 未分配金额红包数量 * 红包放大倍数
int avgRedMaxMoney = redMoney.divide(new BigDecimal(num), ROUNDING_MODE).multiply(TIMES).intValue() * FRACTION_LENGTH;
BigDecimal curRedMoney = new BigDecimal(random.nextInt(avgRedMaxMoney) * 1.00 / FRACTION_LENGTH + "").setScale(SCALE, ROUNDING_MODE);
if(curRedMoney.compareTo(SINGLE_RED_MIN_MONEY) == -1) {
//红包最小值判断:小于最小红包金额,重新计算
return fightLuckRedPacked(redMoney, num, random, ++errorNum);
}
/*if(curRedMoney.compareTo(SINGLE_RED_MAX_MONEY) == 1) {
//红包最大值判断
return fightLuckRedPacked(curRedMoney, num, random, ++errorNum);
}*/
//最少保留红包金额
BigDecimal surplusMinRedMoney = SINGLE_RED_MIN_MONEY.multiply(new BigDecimal(num - 1));
//除当前红包剩余金额
BigDecimal surplusRedMoney = redMoney.subtract(curRedMoney);
if(surplusMinRedMoney.compareTo(surplusRedMoney) == 1) {
return fightLuckRedPacked(redMoney, num, random, ++errorNum);
}
return curRedMoney;
} public static void main(String[] args) {
System.out.println(SplitRedPackes(new BigDecimal("100"), 20));
} }
java 红包规则的更多相关文章
- 《Java编程思想第四版》附录 C Java 编程规则
附录 C Java 编程规则 本附录包含了大量有用的建议,帮助大家进行低级程序设计,并提供了代码编写的一般性指导: (1) 类名首字母应该大写.字段.方法以及对象(句柄)的首字母应小写.对于所有标识符 ...
- Day01_05_Java第一个程序 HelloWorld - java类规则
第一个程序Hello World *基础语法规则: 1. 第一个Java程序 HelloWorld! public class HelloWorld{ public static void main( ...
- java命名规则/规范
Java命名规则: 名称只能由字母.数字.下划线.$符号组成. 不能以数字开头,不能包含空格. 名称不能使用Java中的关键字. Java命名规范: 项目名全部小写: project 包名全部 ...
- java 重载规则
首先看Java重载的规则: 1.必须具有不同的参数列表: 2.可以有不同的返回类型,只要参数列表不同就可以: 3.可以有不同的访问修饰符: 4.可以抛出不同的异常: 5.方法能够在一个类中或者在一个子 ...
- Java命名规则总结
1. JAVA源文件的命名 JAVA源文件名必须和源文件中所定义的类的类名相同. 2. Package的命名 Package名的第一部分应是小写ASCII字符,并且是顶级域名之一,通常是com.edu ...
- java命名规则
java变量命名是不能以#开头的.Java变量的命名规则如下:$ .字母.下划线开头都行,不能以数字开头 后面的可以是数字.字母.下划线, 其他的命名方式,都会报错,且不能运行. 以字母.下划线( _ ...
- [JAVA第二课] java命名规则
Java良好的命名规则以及代码风格可以看出来一个程序员的功底,好多公司也会注重这方面,他们招聘员工在有些时候往往就是根据一个人的代码风格来招人,所以下面就就我知道的代码风格作简要的说明一下.Java命 ...
- Java中==规则
普通对象== 一般说来,java中的==指的是比较两个对象的内存地址是否相同.同时,在java中,一旦使用new关键字,则说明在内存中开辟了一段空间,用于存储对象. 假设我们有一个Person类,请看 ...
- Java 命名规则
http://lpacec.iteye.com/blog/25180包名:包名是全小写的名词,中间可以由点分隔开,例如:java.awt.event; 类名:首字母大写,通常由多个单词合成一个类名,要 ...
随机推荐
- Scala函数式编程——近半年的痛并快乐着
从9月初啃完那本让人痛不欲生却又欲罢不能的<七周七并发模型>,我差不多销声匿迹了整整4个月.这几个月里,除了忙着讨食,便是继续啃另一本"锯著"--<Scala函数 ...
- Ubuntu连接手机步骤
第一次使用adb之前,需要在home/.android里新建adb_usb.ini文件:0x1782. 注:adb已在安装系统后装好,手机要处于开机状态 查看设备命令: $ adb devices 正 ...
- UNIX环境高级编程 标准IO库
标准I/O库处理很多细节,使得便于用户使用. 流和 FILE 对象 对于标准I/O库,操作是围绕 流(stream)进行的.当用标准I/O打开或创建一个文件时,我们已使一个流与一个文件相关联. 对于A ...
- centos7 安装php 5.x.x 报错
错误1: /usr/src/php-5.2.9/ext/dom/node.c:In function 'dom_canonicalization': /usr/src/php-5.2.9/ext/do ...
- phpcms 缓存模板文件
caches\caches_template\default\content 对应模板文件的编译
- SPOJ Favorite Dice(数学期望)
BuggyD loves to carry his favorite die around. Perhaps you wonder why it's his favorite? Well, his d ...
- BZOJ4668 冷战 【LCT】
Description 1946 年 3 月 5 日,英国前首相温斯顿·丘吉尔在美国富尔顿发表"铁幕演说",正式拉开了冷战序幕. 美国和苏联同为世界上的"超级大国&quo ...
- BZOJ3932 CQOI2015 任务查询系统 【主席树】
BZOJ3932 CQOI2015 任务查询系统 Description 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的任务用三元组(Si,Ei, ...
- Toxiproxy 网络情况模式代理
1. 介绍 Toxiproxy is a framework for simulating network conditions. It's made specifically to work in ...
- FastAdmin 无刷新地址改变
FastAdmin 无刷新地址改变 群里有人问 FastAdmin 是不是用了 pjax? 之前有看到 Karson 回复过,其实 FastAdmin 用的是 HTML5 的一个History API ...