【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函数 ...
随机推荐
- 【原创】三分钟教你学会MVC框架——基于java web开发(1)
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用于组织代码用一种业务逻辑和数据显示分离的方法. ...
- 剑英陪你玩转图形学(五)focus
很久没来和大家交流业务(zhuangbi)水平了,最近实在是很忙,报名了小游戏大赛,一点时间都抽不出,已经坑了. 今天抓紧时间和大家介绍一个小效果: 新手引导的时候,我们会需要一种全屏幕黑掉,只有一个 ...
- [SQLServer大对象]——FileTable初体验
阅读导航 启用FILESTREAM设置 更改FILESTRAM设置 启用数据库非事务性访问级别 FileTable 在我接触FileTable之前,存储文件都是存储文件的链接和扩展名到数据,其实并没有 ...
- EF架构~关系表插入应该写在事务里,但不应该是分布式事务
回到目录 这个标题很有意思,关系表插入,就是说主表和外表键在插入时,可能会有同步插的情况,如在建立主表时,扩展表需要同步完成数据的初始化工作,而对于多表插入时,我们为了保证数据的一致性会针它写在事务中 ...
- fir.im Weekly - 1000 个 Android 开源项目集合
冬天到了,适宜囤点代码暖暖身.本期 fir.im Weekly 收集了最近一些不错的 GitHub 源码.开发工具和技术实践教程类文章分享给大家. codeKK - 集合近 1000 Android ...
- 使用JSExcelXML.js导出Excel模板
github地址:https://github.com/464884492/JSExcelXml 业务系统显示效果图 导出模板图 功能描述 世间万物总是相生相克,既然我们的客户要求有导出Ex ...
- 新手入门:史上最全Web端即时通讯技术原理详解
前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...
- 谈谈主函数main
我们来看一下主函数 public class HelloWorld{ public static void main(String[] args){ System.out.println(" ...
- HTML5 学习总结(五)——WebSocket与消息推送
B/S结构的软件项目中有时客户端需要实时的获得服务器消息,但默认HTTP协议只支持请求响应模式,这样做可以简化Web服务器,减少服务器的负担,加快响应速度,因为服务器不需要与客户端长时间建立一个通信链 ...
- 【WP开发】WebView控件应用要点
WebView控件我就不多作详细的介绍,相信大家都懂的,就算你没用过,你看他的名字和长相都知道它的用途了.就是用来显示HTML内容的. 在WP 8.1的Runtime App中,这个控件大致有以下几个 ...