【C#】Excel舍入函数Round、RoundUp、RoundDown的C#版
本人在C#中进行小数舍入的时候常常会怀念Excel中的Round、RoundUp、RoundDown这几个函数,原因就是后者“接地气”,比较符合俺小老百姓的舍入要求,啥“银行家舍入法”就让银行家用去吧。今儿有空,就把它实现了一下,先温习一下这几个Excel函数的功能:
Round(value, digits)
将value按四舍五入法进行舍入,保留digits位小数;当digits为负时,在小数点左侧进行舍入;当value为负时,表现与正数完全相反。
举例:Round(3.145, 2) = 3.15;Round(-3.145, 2) = -3.15;Round(3145, -2) = 3100
RoundUp(value, digits)
按远离 0 的方向,将value向上舍入,保留digits位小数;当digits为负时,在小数点左侧进行舍入
举例:RoundUp(3.111, 2) = 3.12;RoundUp(-3.111, 2) = -3.12;RoundUp(3111, -2) = 3200
RoundDown(value, digits)
按靠近 0 的方向,将value向下舍入,保留digits位小数;当digits为负时,在小数点左侧进行舍入
举例:RoundDown(3.145, 2) = 3.14;RoundDown(-3.145, 2) = -3.14;RoundDown(3145, -2) = 3100
实现原理:
- 对于RoundUp和RoundDown,由于decimal或Math类的Ceiling和Floor方法(下称C/F)只能取整,所以先根据要保留的位数,乘除得到可供C/F方法发挥的新值,然后就可以利用C/F得到舍入后的值,再乘/除回去,得到最终结果。此法市面常见。
举例:1.114向上保留2位,首先1.114x100得到111.4,再用C(111.4)得到112,然后112 / 100,最终得到1.12
问题:由于要先对原值进行乘除,所以对于接近Max/Min、或精度过高的原值,这一步就会造成溢出,所以Up和Down不能应对特别大的值,但日常应用相信没问题。
- 对于RoundEx方法,则直接封装decimal.Round(decimal, MidpointRounding.AwayFromZero)得到结果。
实现说明:
- 以扩展方法提供,兼容常规方法调用方式(废话)。即可以3.145M.RoundEx(2),也可以MathEx.RoundEx(3.145M, 2)
- 每个方法以decimal和double两种类型提供重载,共6个方法
- 以decimal类型为基础进行实现,double版只是重用+类型转换。之所以不对double进行实现,不是因为偷懒,而是因为浮点运算容易扯蛋,如555.55x100=55554.999999999993。关于浮点运算的不可靠性,可参看:http://www.cnblogs.com/ethancai/articles/1237012.html
- 四舍五入函数命名为RoundEx是因为decimal类已经存在一个叫Round的静态方法,如果不错开,将不能以扩展方式3M.Round()进行调用。而且虽然.net在命名上具有极大的包容度,但我认为还是尽量避开FCL命名的好,无谓去“享受”这种自由度
- 几个方法之所以都要先判断一下保留位数,而没有直接使用10的digits次方进行运算,是想尽量沿用decimal类型的原生方法,减少没必要的数学运算。咱追求的不是极简的代码,而是性能。当然,没测试过~鸡蛋飞来中...
废话了一堆,上代码:
/// <summary>
/// 数学类扩展方法
/// </summary>
public static class MathEx
{
/// <summary>
/// 远离 0 向上舍入
/// </summary>
public static decimal RoundUp(this decimal value, sbyte digits)
{
if (digits == )
{
return (value >= ? decimal.Ceiling(value) : decimal.Floor(value));
} decimal multiple = Convert.ToDecimal(Math.Pow(, digits));
return (value >= ? decimal.Ceiling(value * multiple) : decimal.Floor(value * multiple)) / multiple;
} /// <summary>
/// 靠近 0 向下舍入
/// </summary>
public static decimal RoundDown(this decimal value, sbyte digits)
{
if (digits == )
{
return (value >= ? decimal.Floor(value) : decimal.Ceiling(value));
} decimal multiple = Convert.ToDecimal(Math.Pow(, digits));
return (value >= ? decimal.Floor(value * multiple) : decimal.Ceiling(value * multiple)) / multiple;
} /// <summary>
/// 四舍五入
/// </summary>
public static decimal RoundEx(this decimal value, sbyte digits)
{
if (digits >= )
{
return decimal.Round(value, digits, MidpointRounding.AwayFromZero);
} decimal multiple = Convert.ToDecimal(Math.Pow(, -digits));
return decimal.Round(value / multiple, MidpointRounding.AwayFromZero) * multiple;
} /// <summary>
/// 远离 0 向上舍入
/// </summary>
public static double RoundUp(this double value, sbyte digits)
{
return decimal.ToDouble(Convert.ToDecimal(value).RoundUp(digits));
} /// <summary>
/// 靠近 0 向下舍入
/// </summary>
public static double RoundDown(this double value, sbyte digits)
{
return decimal.ToDouble(Convert.ToDecimal(value).RoundDown(digits));
} /// <summary>
/// 四舍五入
/// </summary>
public static double RoundEx(this double value, sbyte digits)
{
return decimal.ToDouble(Convert.ToDecimal(value).RoundEx(digits));
}
}
- 文毕 -
【C#】Excel舍入函数Round、RoundUp、RoundDown的C#版的更多相关文章
- Excel—数学函数
		
ROUND(四舍五入函数)就是说把一个小数点后多位的数四舍五入小数点位数的函数 函数语法:ROUND(哪个数,要四舍五入到小数点后几位) ROUNDUP(保留小数点几位后进位的函数)就是说要保留一个小 ...
 - 浅谈Excel开发:五 Excel RTD函数
		
上文介绍了Excel中的UDF函数,本文介绍一下同样重要的RTD函数.从Excel 2002开始,Excel引入了一种新的查看和更新实时数据的机制,即real-time data简称RTD函数 ...
 - 浅谈Excel开发:四 Excel 自定义函数
		
我们知道,Excel中有很多内置的函数,比如求和,求平均,字符串操作函数,金融函数等等.在有些时候,结合业务要求,这些函数可能不能满足我们的需求,比如我想要一个函数能够从WebService上获取某只 ...
 - C#操作Excel的函数
		
对于Excel的数据处理功能,大家都已经了解. 我们经常需要将数据导入到Excel,或直接打开Excel文档,读写文件操作,这需要用到ExcelHelper类,有了这个类,这些操作大大的减少我们工作量 ...
 - Excel常用函数大全
		
1.ABS函数 函数名称:ABS 主要功能:求出相应数字的绝对值. 使用格式:ABS(number) 参数说明:number代表需要求绝对值的数值或引用的单元格. 应用举例:如果在B2单元格 ...
 - Excel REPT函数使用
		
需要制作1K大小的数据 使用Excel REPT函数可以迅速制造 Excel REPT 函数 =REPT(1,1024) 结果直接黏贴进txt文件,注意删除尾空格.
 - Excel 自定义函数
		
浅谈Excel开发:四 Excel 自定义函数 我们知道,Excel中有很多内置的函数,比如求和,求平均,字符串操作函数,金融函数等等.在有些时候,结合业务要求,这些函数可能不能满足我们的需求,比 ...
 - Excel里函数中的万金油,你确定不要点进来看看?
		
Excel里函数中的万金油,你确定不要点进来看看? 来源:EXCELHome Excel里有个号称"万能"的函数组合,这个函数组合就是INDEX+SMALL+IF,很多应用场合都能 ...
 - Excel IF函数怎么用
		
本例主要介绍Excel表格中IF函数的用法,包括基本用法.单条件.多条件表达及在数组函数中的用法和在数组函数中怎么表达多条件和单条件. 工具/原料 Excel IF函数语法介绍: 1 IF函数 ...
 
随机推荐
- FusionCharts简单教程(七)-----使用FusionCharts实现下钻功能
			
前面介绍的FusionCharts都是对FusionCharts的基本属性进行操作,下面几篇博文就FusionCharts的高级特性做一个介绍,包括:添加下钻链接.使用Style样式定制图 ...
 - Jquery相册插件(开源下载)
			
一,导言 上次 “不定义JQuery插件,不要说会JQuery” 的博客写的肤浅,漏洞百出,而且最重要的是从理论上说如何定义一个jQuery插件,没有实质性的写一个jQuery插件出来,这未免是纸上谈 ...
 - [ZigBee] 8、ZigBee之UART剖析·二(串口收发)
			
前言:上一节讲UART基本知识介绍完了,并深入剖析了一个串口发送工程,本节将进一步介绍串口收发! 1.初始化 在串口初始化部分,和上一节不同的地方是: 51 U0CSR |= 0x40; //允许接收 ...
 - Git Day01,仓库,commit,版本切换
			
1st,创建版本库: 2nd,添加文件: 3rd,修改文件,并提交: 4th,版本切换:git log查看版本:版本回退: 又回到原始版本了: 回到“未来”: 今天就到这里,明天继续.Git确实挺 ...
 - webservice3
			
什么是bottom up 什么是top down 通过浏览器访问如 http://localhost:8080/HelloWS/services/HelloWSsss?wsdl 获取的 wsdl, ...
 - jsp中运用application实现共享留言板功能
			
jsp中application的知识点总结: 1.一个Web应用程序启动后,将会自动创建一个application对象,在整个应用程序的运行过程中只有这一个application对象,即所有访问该网站 ...
 - 每天一个linux命令(58):telnet命令
			
telnet命令通常用来远程登录.telnet程序是基于TELNET协议的远程登录客户端程序.Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式.它为用户 ...
 - EF架构~关于多对多关系表无法更新与插入的问题
			
回到目录 在EF里,我们设计模型时,会设计到多对多关系,在EF里会把这种关系会转成两个一对多的关系表,这是比较友好的,因为多对多来说,对于业务本身没什么意思,所以隐藏了,没什么坏处,但对于这个隐藏来说 ...
 - 20_学生选课数据库SQL语句练习题1
			
25.查询95033班和95031班全体学生的记录. select * from STUDENT t,SCORE s where t.sclass=95033 or t.sclass=95031 26 ...
 - Atitit 图像处理 公共模块 矩阵扫描器
			
Atitit 图像处理 公共模块 矩阵扫描器 1.1. 调用说明对矩阵像素遍历处理调用1 2. 矩阵扫描器主题结构1 2.1. 主要说明 从像素点开始填充矩阵1 2.2. 得到模板中心点所对应的图像坐 ...