Bigdecimal随机拆分多个 随机红包

33 篇文章 0 订阅

Bigdecimal随机拆分多个

 List<BigDecimal> amounts = SplitBigDecimalUtils
                        .splitBigDecimalFromRange(amount, activeVoucherConfig.getSplit_number(), 1, min, amount.subtract(min));
package com.plouto.common.utils;

import com.google.common.collect.Lists;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;

/**
 * @Author: Bumblebee
 * @date 19-8-6 下午4:22
 * @description:
 */
public class SplitBigDecimalUtils {

    /**
     * 每个红包最小金额,单位为与scale有关,例如scale为2,单位为分
     */
    private static final int MIN_MONEY = 1;

    /**
     * 红包金额的离散程度,值越大红包金额越分散
     */
    private static final double DISPERSE = 1;

    private static final BigDecimal pow = new BigDecimal(10);

    /**
     * 将一个BigDecimal 切分成指定个数指定精度指定范围的若干个数,如果范围设置不当,前面随机的数较小,可能会导致最后一个数过大超出范围
     * @param amount 总数量
     * @param count 总个数
     * @param scale 精度
     * @param min 最大值
     * @param max 最小值
     * @return
     */
    public static List<BigDecimal> splitBigDecimalFromRange(BigDecimal amount, int count, int scale, BigDecimal min, BigDecimal max) {
        BigDecimal total = new BigDecimal(0);
        List<BigDecimal> list = Lists.newArrayList();
        for (int i = 0; i < count; i++) {
            BigDecimal tem = getOneRedBag(amount.subtract(total), count - i, scale, min, max);
            total = total.add(tem);
            list.add(tem);
        }
        return list;
    }

    public static void main(String[] args) {
        //总量
        BigDecimal amount = new BigDecimal(16);
        BigDecimal min = new BigDecimal(0.1);
        BigDecimal max = amount.subtract(min);

        List<BigDecimal> bigDecimals = splitBigDecimalFromRange(amount, 4, 2, min, max);
        System.out.println(12);
    }



    private static BigDecimal getOneRedBag(BigDecimal amount, int count, int scale, BigDecimal min, BigDecimal max) {
        // 转成int做运算
        int amountInt = amount.setScale(scale, RoundingMode.HALF_UP).multiply(pow).intValue();
        int minInt = min.setScale(scale, RoundingMode.HALF_UP).multiply(pow).intValue();
        int maxInt = max.setScale(scale, RoundingMode.HALF_UP).multiply(pow).intValue();
        if (amountInt < minInt * count) {
            throw new RuntimeException("最小值设置过大");
        }
        if (minInt > maxInt){
            throw new RuntimeException("最大值小于最小值");
        }
        if (maxInt * count < amountInt){
            throw new RuntimeException("最大值设置过小");
        }
        //最大值不能大于总金额
        maxInt = maxInt > amountInt ? amountInt : maxInt;
        //randomBetweenMinAndMax()上面有这个方法
        return new BigDecimal(randomBetweenMinAndMax(amountInt, count, minInt, maxInt)).divide(pow, scale,
                RoundingMode.HALF_UP);
    }

    /**
     * 在最小值和最大值之间随机产生一个
     *
     * @param money
     * @param count
     * @param min   : 最小量
     * @param max   : 最大量
     * @return
     */
    public static int randomBetweenMinAndMax(int money, int count, int min, int max) {
        //最后一个直接返回
        if (count == 1) {
            return money;
        }
        //最小和最大金额一样,返最小和最大值都行
        if (min == max) {
            return min;
        }
        //最小值 == 均值, 直接返回最小值
        if (min == money / count) {
            return min;
        }
        //min<=随机数bag<=max
        int bag = ((int) Math.rint(Math.random() * (max - min) + min));

        //剩余的均值
        int avg = (money - bag) / (count - 1);
        //比较验证剩余的还够不够分(均值>=最小值 是必须条件),不够分的话就是最大值过大
        if (avg < MIN_MONEY) {
            /*
             * 重新随机一个,最大值改成本次生成的量
             * 由于 min<=本次金额bag<=max, 所以递归时bag是不断减小的。
             * bag在减小到min之间一定有一个值是合适的,递归结束。
             * bag减小到和min相等时,递归也会结束,所以这里不会死递归。
             */
            return randomBetweenMinAndMax(money, count, min, bag);
        } else {
            return bag;
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
如果你想要实现多个BigDecimal相减,可以使用以下方法: ```java public static BigDecimal getBigDecimalDifference(BigDecimal i, BigDecimal... arg) { BigDecimal difference = i; for (BigDecimal b : arg) { difference = difference.subtract(b); } return difference; } ``` 你可以将需要相减的BigDecimal作为参数传入这个方法,然后通过循环遍历每个BigDecimal,使用subtract方法进行相减操作。最后返回得到的差值。 例如,假设有以下的代码: ```java BigDecimal b1 = new BigDecimal("10"); BigDecimal b2 = new BigDecimal("5"); BigDecimal b3 = new BigDecimal("3"); BigDecimal result = getBigDecimalDifference(b1, b2, b3); System.out.println(result); // 输出为2 ``` 在这个例子中,我们将b1、b2和b3作为参数传入getBigDecimalDifference方法,然后得到的结果为2,即10 - 5 - 3的差值。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [多个BigDecimal数相加相减](https://blog.csdn.net/chesou8240/article/details/100633791)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [BigDecimal用法](https://blog.csdn.net/baidu_41634343/article/details/90439360)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值