当前位置: 首页 > news >正文

算法:四舍六入五成双 ,保留三位有效数字

     在实际的生产制造统计中,会有精度丢失的情况. 倘若按照 我们平常所用的 四舍五入,(1234舍掉, 56789 进位)

这样会使整体数据偏大(理论模型).

      为了使整体数据保持平均,生产制造有这样一种计算方式,也就是 四舍六入无成双.

 

例如保留3位有效数字:  

  1.235 => 1.235

  1.2354=>1.235 (0.0004舍掉)

  1.2355=>1.236 (0.0005前面是奇数,进位)

  1.2365=>1.236 (0.0005前面是偶数,舍弃)

C# 代码如下

/// <summary>
/// 格式化 Decimal 数字  用于有效计算
/// </summary>
/// <param name="ori"></param>
/// <returns></returns>
/// <remarks></remarks>
public static decimal FormatDecimal(decimal ori)
{
    if (ori == 0) {
        return 0;
    }

    decimal num = ori;
    decimal result = 0m;
    int zoome = 1;

    //小于100的数, 数字放大 10的  指数倍,直到 数字 大于等于100

    while (num < 100) {
        num = num * 10;
        zoome = zoome * 10;
    }

    int int1 = Math.Floor(num);
    decimal d1 = Math.Floor(num) + 0.5;

    // 四舍六入
    // 5 看尾数 和奇偶

    if (num > d1) {
        //如果 5后面有尾数, 进位
        result = int1 + 1;
    } else if (num == d1) {
        // 看前一位  偶数不变,奇数 +1
        if (int1 % 2 == 0) {
            result = int1;
        } else {
            result = int1 + 1;
        }
    } else {
        //整数
        result = int1;
    }

    //有效数字取到以后 缩小到原来的数量级
    result = result / zoome;
    return result;
}

/// <summary>
/// 格式化字符串显示 Decimal 数字
/// </summary>
/// <param name="ori"></param>
/// <returns></returns>
/// <remarks></remarks>
public static string ShowDecimal(decimal ori)
{

    if (ori == 0) {
        return "0";
    }
    //首先  得到 格式化之后的数据, 有效数字
    ori = FormatDecimal(ori);

    string strNum = "";
    decimal num = ori;

    //判断是不是 3位及3位以上数字 直接取整数部分

    if (num >= 100) {
        strNum = num.ToString();
    } else if (num > 0) {
        // 三位数以下, 涉及到 取小数点
        string s = num.ToString();
        // 没有小数点, 先补齐 小数点位数
        if (s.Contains(".")) {
            s = s + "00";
        } else {
            s = s + ".00";
        }


        // 遍历取 3位有效数字
        char[] array = s.ToCharArray();
        int start = 0;

        for (int i = 0; i <= array.Length - 1; i++) {
            if (start == 3) {
                break; // TODO: might not be correct. Was : Exit For
            }

            if (array[i] == ".") {
                strNum = strNum + ".";
            } else {
                int t = int.Parse(array[i]);
                if (t > 0) {
                    start = start + 1;
                    strNum = strNum + t;
                } else if (t == 0) {
                    if (start > 0) {
                        start = start + 1;
                        strNum = strNum + t;
                    } else {
                        strNum = strNum + t;
                    }
                }
            }
        }
    }


    return strNum;

}
View Code

 

SQL 代码如下

create function [dbo].[func_formatDecimal](@wgt decimal(16,6)) 

  returns numeric(16,3) 

  as 

   begin 

      if @wgt = 0 

        begin 

          return 0 

        end   

      declare @num  decimal(16,6),@result numeric(16,3),@zoome integer 

      set  @num = @wgt 

      set @result = 0 

      set @zoome = 1 

      --小于100的数, 数字放大 10 的倍数 

      while @num<100 

       begin 

          set @num = @num * 10 

          set @zoome = @zoome * 10 

       end 

     declare @int1 integer,@d1 numeric(16,1)   

     set @int1 =  floor(@num) 

     set @d1 = floor(@num)+0.5 

      --四舍六入 

      --5 看尾数和奇偶 

      if @num>@d1  

        begin 

          set @result = @int1+1 

        end 

      else if @num =@d1 

        begin 

         --看前一位 偶数不变,奇数+1 

            if @int1 % 2 = 0 

              set @result = @int1 

            else  

              set @result = @int1+1  

        end   

       else 

         set @result = @int1  

     set @result = @result / @zoome 

     return(@result) 

   end 
View Code

 

  本人才疏学浅,如果你有更好的方法,欢迎留言讨论.

 

转载于:https://www.cnblogs.com/mjxxsc/p/4048715.html

相关文章:

  • VS 编码规范---- 代码注释设置
  • Tuxedo入门学�
  • mybatis的collection查询问题以及使用原生解决方案的结果
  • javaweb_CSS
  • sam哥其实是个安静的美男子...
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • 经典面试题1
  • JAVA学习路线 零基础新手必备
  • Flask+jinja2 开发Puppet用户和节点管理系统
  • 痞子衡嵌入式:如果i.MX RT是一匹悍马,征服它时别忘了用马镫MCUBootUtility
  • 武汉大学2014年基础数学复试试题参考解答
  • chown: changing ownership of `.': Invalid argument
  • 面试题:数组原型上实现一个去重的方法
  • ×××案例之一路由之间的×××
  • Spring Framework 5.2.0.M1 发布
  • 【技术性】Search知识
  • 2017届校招提前批面试回顾
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • iOS | NSProxy
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • JS学习笔记——闭包
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • ng6--错误信息小结(持续更新)
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • Spring核心 Bean的高级装配
  • sublime配置文件
  • ViewService——一种保证客户端与服务端同步的方法
  • vue-router的history模式发布配置
  • 关于 Cirru Editor 存储格式
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 学习使用ExpressJS 4.0中的新Router
  • 译自由幺半群
  • 仓管云——企业云erp功能有哪些?
  • #define、const、typedef的差别
  • (SpringBoot)第七章:SpringBoot日志文件
  • (补)B+树一些思想
  • (动态规划)5. 最长回文子串 java解决
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (算法二)滑动窗口
  • (学习日记)2024.01.19
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • (转)jdk与jre的区别
  • .NET CF命令行调试器MDbg入门(一)
  • .NET Compact Framework 3.5 支持 WCF 的子集
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET多线程执行函数
  • .NET框架
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • /etc/sudoer文件配置简析
  • [AutoSar]工程中的cpuload陷阱(三)测试
  • [BJDCTF2020]The mystery of ip
  • [C/C++]数据结构----顺序表的实现(增删查改)