首页 > 编程语言 >数值修约算法

数值修约算法

时间:2023-07-17 18:13:44浏览次数:59  
标签:修约 BigDecimal rule 数值 算法 num value2 HALF decimalPlaces

1、Java版本

点击查看代码
import com.github.pagehelper.util.StringUtil;
import static cn.hutool.core.convert.Convert.toStr;
import static org.springframework.util.ObjectUtils.isEmpty;

/**
     * 数值、精度、修约规则
     * <pre>
     *     实例代码:
     *     System.out.println(evenRound(1.1345, 0.001, "四舍五入"));
     *     System.out.println(evenRound(1.1345, 0.001, "四舍六入"));
     * </pre>
     *
     * @param value:数值
     * @param places:精度(1、0.5、10、0.1、0.01...)
     * @param even:修约(四舍五入、四舍六入)
     * @return {BigDecimal}
     */
    public static String evenRound(Object value, Object places, Object even) {
        if (places == null || even == null) {
            String value2 = toStr(value);
            return value2;
        }
        String value2 = toStr(value);
        String places2 = toStr(places);
        String even2 = toStr(even);
        //数值和精度 不可以为空
        if (StringUtil.isEmpty(value2) || StringUtil.isEmpty(places2) || StringUtil.isEmpty(even2)) return value2;
        try {
            BigDecimal num = new BigDecimal(value2);
            Integer decimalPlaces = 0;
            //默认是 四舍六入
            Integer evenRound = (even2.indexOf("五") > -1 || even2.indexOf("5") > -1 || even2.indexOf("伍") > -1) ? 5 : 6;

            if (places2.equals("0.5")) {
                //TODO 精度为 0.5 时
                //(0.75 * 2).修约 / 2
                BigDecimal rule = new BigDecimal("2");//系数
                //保留0位小数
                decimalPlaces = 0;
                if (evenRound == 5) {
                    //四舍五入
                    value2 = ((num.multiply(rule)).setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP).divide(rule, 4, BigDecimal.ROUND_HALF_UP)).toString();
                } else {
                    //四舍六入
                    value2 = ((num.multiply(rule)).setScale(decimalPlaces, BigDecimal.ROUND_HALF_EVEN).divide(rule, 4, BigDecimal.ROUND_HALF_EVEN)).toString();
                }
                value2 = numDecimal(value2, 1);
            } else if (places2.equals("5")) {
                //TODO 精度为 ”5“ 时 ,个位只有(0 | 5)
                //(0.75 * 0.2).修约 / 0.2
                BigDecimal rule = new BigDecimal("0.2");//系数
                //保留0位小数
                decimalPlaces = 0;
                if (evenRound == 5) {
                    //四舍五入
                    value2 = ((num.multiply(rule)).setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP).divide(rule, 4, BigDecimal.ROUND_HALF_UP)).toString();
                } else {
                    //四舍六入
                    value2 = ((num.multiply(rule)).setScale(decimalPlaces, BigDecimal.ROUND_HALF_EVEN).divide(rule, 4, BigDecimal.ROUND_HALF_EVEN)).toString();
                }
                value2 = numDecimal(value2, 0);
            } else if (places2.equals("10")) {
                //TODO 精度为 ”10“ 时
                //(0.75 / 10).修约 * 10
                BigDecimal rule = new BigDecimal("10");//系数
                //保留0位小数
                decimalPlaces = 0;
                if (evenRound == 5) {
                    //四舍五入
                    value2 = ((num.divide(rule)).setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP).multiply(rule)).toString();
                } else {
                    //四舍六入
                    value2 = ((num.divide(rule)).setScale(decimalPlaces, BigDecimal.ROUND_HALF_EVEN).multiply(rule)).toString();
                }
            } else {
                //0.1、0.01
                String[] split = places2.split("\\.");//截取小数点
                if (split.length > 1) {
                    //拿到小数点后几位,就保留几位小数
                    decimalPlaces = split[1].length();
                }
                if (evenRound == 5) {
                    //四舍五入
                    value2 = num.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP).toString();
                } else {
                    //四舍六入
                    value2 = num.setScale(decimalPlaces, BigDecimal.ROUND_HALF_EVEN).toString();
                }
                value2 = numDecimal(value2, decimalPlaces);
            }
        } catch (Exception e) {
            System.err.println(value + "," + places + "," + even + "\t修约规则有误:" + e.getMessage());
        }
        return value2;
        //规则:
        //四舍六入五考虑,
        //五后非零就进一,
        //五后皆零看奇偶,
        //五前为偶应舍去,
        //五前为奇要进一。
    }

    /**
     * 小数位不够自动补 “0”
     *
     * @param num {数值}
     * @param len {保留几位小数}
     */
    public static String numDecimal(String num, int len) {
        num = org.springframework.util.ObjectUtils.isEmpty(num) ? "0" : toStr(num);
        len = org.springframework.util.ObjectUtils.isEmpty(len) ? 0 : len;
        if (len == 0) return num.split("\\.")[0];
        String decimal;
        if (num.indexOf(".") == -1 && len != 0) num += ".0";
        String[] split = num.split("\\.");
        decimal = split[1];//12
        num = split[0];
        if (decimal.length() > len) {
            decimal = decimal.substring(0, len);
        } else {
            while (decimal.length() != len) {
                decimal += "0";
            }
        }
        return num + "." + decimal;
    }

2、JavaScript版本

点击查看代码
/**
 * 数值修约算法(四舍六入)
 * @param num
 * @param decimalPlaces{number}
 * @returns {number}
 * @see https://www.jianshu.com/p/d329fe017520
 */
export function sixRound(num, decimalPlaces) {
  let d = decimalPlaces || 0;
  let m = Math.pow(10, d);
  let n = +(d ? num * m : num).toFixed(8);
  let i = Math.floor(n), f = n - i;
  let e = 1e-8;
  let r = (f > 0.5 - e && f < 0.5 + e) ?
    ((i % 2 === 0) ? i : i + 1) : Math.round(n);
  return d ? r / m : r;
}

标签:修约,BigDecimal,rule,数值,算法,num,value2,HALF,decimalPlaces
From: https://www.cnblogs.com/fzxx/p/17560849.html

相关文章

  • 算法_贝叶斯网络学习_bayesian networks
    基本概念条件概率联合概率边缘概率链式法则随机变量的独立性条件独立性贝叶斯规则、贝叶斯概率推理和贝叶斯网络模型。stochastic,主要用作形容词,主要意思为“随机的;猜测的”R语言包R语言用lme4多层次(混合效应)广义线性模型(GLM),逻辑回归分析lme4广义线性混合模型......
  • 拓扑排序算法相关的知识点总结
    拓扑排序算法相关的知识点总结拓扑排序算法是一种对有向无环图(DAG)进行排序的方法,它可以将图中的所有顶点排成一个线性序列,使得对于任意一对顶点u和v,如果存在一条从u到v的有向边,那么u在序列中必然出现在v之前。拓扑排序算法可以用来解决一些依赖关系的问题,例如课程安排、工程进度......
  • java原地算法
    原地算法:优化内存空间的Java编程技巧随着计算机科学的发展,我们不断追求更高效的算法和更低的内存消耗。在Java编程中,原地算法是一种常见的优化技巧,它可以大大减少对内存的使用,提高程序的性能。本文将介绍什么是原地算法,为什么要使用它以及如何在Java中实现。什么是原地算法?原地......
  • 代码随想录算法训练营第三十二天| 343. 整数拆分 96.不同的二叉搜索树
     343.整数拆分要求:将一个正数拆分成N个正整数,使得这N个正整数的乘机是最大的思路:DP数组:dp[n]N的时候,它的乘机最大值注意:不是i*dp[n-i]就是最大值,因为如果用dp就证明要开始拆分了,如果我不拆分,就是用的这两个数的话,那么就是单纯的i*(n-i)代码:1//要求:将N拆分成K......
  • 文心一言 VS 讯飞星火 VS chatgpt (60)-- 算法导论6.4 4题
    文心一言VS讯飞星火VSchatgpt(60)--算法导论6.44题四、证明:在最坏情况下,HEAPSORT的时间复杂度是Ω(nlgn)。文心一言:要证明在最坏情况下,HEAPSORT的时间复杂度是Ω(nlogn),我们需要考虑在何种情况下堆排序的时间复杂度最低。在堆排序中,构建最大堆的时间复杂度为O(n),......
  • m基于FPGA的带相位偏差64QAM调制信号相位估计和补偿算法verilog实现,包含testbench
    1.算法仿真效果 本系统进行了Vivado2019.2平台的开发,其中Vivado2019.2仿真结果如下:   将FPGA的仿真结果导入到matlab中,显示星座图,结果如下所示:    2.算法涉及理论知识概要         在现代通信系统中,调制技术是实现高速数据传输和频谱效率优化的......
  • 二进制相加算法
    本文主要写二进制相加(<fontcolor='gray'>二进制相加</font>)二进制相加二进制相加是一种特殊的加法运算,它只适用于二进制数。在计算机科学中,二进制相加被广泛应用于位运算、逻辑运算和数据存储等方面。以下是二进制相加的一些作用:位运算:二进制相加是位运算中的一种基本......
  • m基于FPGA的带相位偏差64QAM调制信号相位估计和补偿算法verilog实现,包含testbench
    1.算法仿真效果本系统进行了Vivado2019.2平台的开发,其中Vivado2019.2仿真结果如下:将FPGA的仿真结果导入到matlab中,显示星座图,结果如下所示:2.算法涉及理论知识概要在现代通信系统中,调制技术是实现高速数据传输和频谱效率优化的重要手段。其中,64QAM调制技术是一种常见的高......
  • 文心一言 VS 讯飞星火 VS chatgpt (60)-- 算法导论6.4 4题
    文心一言VS讯飞星火VSchatgpt(60)--算法导论6.44题四、证明:在最坏情况下,HEAPSORT的时间复杂度是Ω(nlgn)。文心一言:要证明在最坏情况下,HEAPSORT的时间复杂度是Ω(nlogn),我们需要考虑在何种情况下堆排序的时间复杂度最低。在堆排序中,构建最大堆的时间复杂度为O(n),这是因......
  • PID算法:标准PID算法的一些改进措施
    前面的几篇文章分别分享了PID算法的原理、增量式和位置式PID算法的区别、以及过程控制中一些重要的指标,感兴趣的朋友可以回看之前的文章或者自行查阅资料。在实际项目中,使用数字PID算法对系统的被控量进行控制的时候,有时候并不是仅仅的使用简单的增量式或者位置式的PID就完成了对系......