认证高级PHP讲师
double min = 0.0001; double max = 10; // 总和 int cnt = 5; // 数量 int scl = 4; // 小数最大位数 int pow = (int) Math.pow(10, scl); // 用于提取指定小数位 double sum = 0; // 用于验证总和 double one ; for (int i = 0; i < cnt; i ++) { if ( i < cnt - 1 ) { // min~max 指定小数位的随机数 one = Math.floor((Math.random() * (max - min) + min) * pow) / pow; } else { one = max; } max -= one; sum += one; // 输出 System.out.printf("%.4f\r\n", one); } // 验证 System.out.println(sum); /* 演示输出: 6.7665 1.7457 0.0602 1.0894 0.3382 10.0 */
如果你想随机数间的差距更小点,可以修改 one 的计算公式,如把 max - min 更换成 max / (cnt - i)。当然你还得注意 min 的取值,避免最后算出 one 为负数。
如果这是题主的考试题,我想考点应该在取指定 m~n 之间的随机数吧。看在我费劲答的份上,路过的兄弟们给个赞呗。
import java.util.ArrayList; import java.util.List; import java.util.Random; /** * Created by Jackie on 2016/7/20. */ public class RedEnvelopRandom { private static final Random random = new Random(); /** * 返回红包数集合 * * @param count 红包个数 * @param digits 小数位数 * @param sum 红包金额总和 * @return 红包随机数集合 */ public static List<Float> getRandomNum(int count, int digits, int sum) { /** 结果集合 */ List<Float> resultList = new ArrayList<Float>(); /** 临时Integer集合 */ List<Integer> tempList = new ArrayList<Integer>(); /** 已生成的随机数和 */ int value = 0; /** 记录每次生成的随机数 */ int tempRandom; /** 先将和乘以10^digits,当整数处理 */ sum = sum * (int) Math.pow(10, digits); //随机产生0-sum*digits之间的随机数,执行count-1 for (int i = 1; i < count; i++) { //前面产生的随机数的和 value += tempList.size() == 0 ? 0 : tempList.get(i - 2); //保证每次的随机数产生后,余下的值至少够分 tempRandom = random.nextInt(sum - count + i - value) + 1; tempList.add(tempRandom); } //最后剩下的值,保证总和不变 value += tempList.size() == 0 ? 0 : tempList.get(count - 2); tempList.add(sum - value); //除以10*digits,得到小数 for (Integer temp : tempList) { resultList.add(new Float(temp) / (int) Math.pow(10, digits)); } return resultList; } }
只能保证和相等,但是是结果不是很均匀,往往头重脚轻
如果你想随机数间的差距更小点,可以修改 one 的计算公式,如把 max - min 更换成 max / (cnt - i)。当然你还得注意 min 的取值,避免最后算出 one 为负数。
如果这是题主的考试题,我想考点应该在取指定 m~n 之间的随机数吧。看在我费劲答的份上,路过的兄弟们给个赞呗。
只能保证和相等,但是是结果不是很均匀,往往头重脚轻