JAVA使用最大余额法来处理百分比不是百分百问题

此方法主要是一个一个类型去做计算

先创建一个实体类,来做计算的值去

package com.jdz.mediate_web.model.dto;

import lombok.Data;

@Data
public class ProportionRiskLevel {

    /**
     * 风险类型
     */
    private String type;

    /**
     * 从数据库计算获得正常值
     */
    private double normalDate;

    /**
     * 放大倍数值
     */
    private double amplifiedData;

    /**
     * 放大倍数整数值
     */
    private Long amplifiedIntegerData;

    /**
     * 放大倍数小数
     */
    private double fractionalPart;

}

当创建了基本值计算的实体类后,将获取到的值进行基本运算

private ProportionRiskLevel proportionNumber(String type, Integer number, Integer sum){
        ProportionRiskLevel proportionRiskLevel = new ProportionRiskLevel();
        //除法,将数量去除总数量,得到的值放大10000倍
        double doubleValue = new BigDecimal(number.toString()).divide(new BigDecimal(sum.toString()), 20, ROUND_UP)
                .multiply(new BigDecimal(10000)).doubleValue();
        proportionRiskLevel.setAmplifiedData(doubleValue);
        long longValue = (long) doubleValue;
        proportionRiskLevel.setAmplifiedIntegerData(longValue);
        // 原数减去整数部分,为小数部分
        double fractionalPart = new BigDecimal(String.valueOf(new Double(doubleValue))).subtract(new BigDecimal(longValue)).doubleValue();
        proportionRiskLevel.setFractionalPart(fractionalPart);
        proportionRiskLevel.setType(type);
        return proportionRiskLevel;

    }

在处理占百分比的时候,我使用的单个单个值得处理,但是先获取到所有值进行一个计算,计算后得值会进行一个倒叙,因为当其有正好可以整除得值不进行倒叙处理,整数值就会进行加1处理

拿放大倍数得值减掉放大倍数得整数值,正常会得到误差数得值,得到放大倍数得整数值进行+1处理

//排序
        List<ProportionRiskLevel> proportionRiskLevelListDesc = proportionRiskLevelList.stream()
                .sorted(Comparator.comparing(ProportionRiskLevel::getFractionalPart).reversed()).collect(Collectors.toList());
        double sumOriginalData = proportionRiskLevelListDesc.stream().mapToDouble(ProportionRiskLevel::getAmplifiedData).summaryStatistics().getSum();
        double sumNumberData = proportionRiskLevelListDesc.stream().mapToDouble(ProportionRiskLevel::getAmplifiedIntegerData).summaryStatistics().getSum();
        long longValue = new BigDecimal(sumOriginalData).subtract(new BigDecimal(sumNumberData)).setScale(0, ROUND_UP).longValue();


        if (longValue >= 0){
            for (int i=0;i<proportionRiskLevelListDesc.size();i++){
                ProportionRiskLevel proportionRiskLevel = proportionRiskLevelListDesc.get(i);
                if (i < longValue){
                    proportionRiskLevel.setAmplifiedIntegerData(proportionRiskLevel.getAmplifiedIntegerData()+1);
                }
                proportionRiskLevel.setNormalDate((double) proportionRiskLevel.getAmplifiedIntegerData() / 100);

            }
        }

目前这个方法适用于超出百分比得值,当低于百分比得值需要做处理得时候,可以根据具体情况来做对应处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在计算百分比的时候,需要注意精度问题。如果将两个百分数直接相加,可能出现精度误差。例如,如果是将25%和75%相加: ```java double percentage1 = 25.0; // 25% double percentage2 = 75.0; // 75% // 将百分数转换为小数 double decimal1 = percentage1 / 100.0; double decimal2 = percentage2 / 100.0; // 计算相加后的结果 double result = decimal1 + decimal2; // 将结果转换为百分数格式输出 String output = String.format("%.2f%%", result * 100.0); System.out.println(output); // 输出结果为 "100.00%" ``` 结果输出100%,但是如果将25%和27%相加: ```java double percentage1 = 25.0; // 25% double percentage2 = 27.0; // 27% // 将百分数转换为小数 double decimal1 = percentage1 / 100.0; double decimal2 = percentage2 / 100.0; // 计算相加后的结果 double result = decimal1 + decimal2; // 将结果转换为百分数格式输出 String output = String.format("%.2f%%", result * 100.0); System.out.println(output); // 输出结果为 "52.00%" ``` 结果输出为52%,不是预期的52%。这是因为两个百分数转换成小数相加后,再将结果转换为百分数时,可能出现精度误差。为了避免这种情况,可以使用`BigDecimal`类进行计算,保证精度不出现误差。例如: ```java BigDecimal percentage1 = new BigDecimal("25"); // 25% BigDecimal percentage2 = new BigDecimal("27"); // 27% // 计算相加后的结果 BigDecimal result = percentage1.add(percentage2); // 将结果转换为百分数格式输出 String output = result.toString() + "%"; System.out.println(output); // 输出结果为 "52%" ``` 在上面的代码中,我们使用`BigDecimal`类进行计算,并且保留了百分数的整数部分。最后再将结果转换为字符串输出。这样可以避免精度误差的问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值