https://code.google.com/p/dotnet-big-decimal/

这是个BigDecimal类的开源项目,支持Operators +- and *

俺给改了改,加上了除法。原来的BigDecimal项目没有整数部分的长度属性,所以没有直接用BigInteger来实现除法,而是自己处理字符串,同时由于.Net4.0的BigInteger类 Parse和ToString方法效率极低,导致这个类效率不高,只能凑合用。

        public static BigDecimal operator /(BigDecimal left, BigDecimal right)
{
var scale = Math.Max(left.scale, right.scale);
string decimal1 = left.ToString();
string decimal2 = right.ToString(); BigDecimal value = BigDecimal.Parse(Division(decimal1, decimal2, scale));
return value;
} /// <summary>
/// 计算除法,精度由CustomScale决定,超过部分直接截去。如果CustomScale小于0,表示精度由前两个参数的最长小数位决定。
/// </summary>
private static string Division(string decimal1, string decimal2, int CustomScale)
{
//算法:把两个参数的小数部分补0对齐,整数部分确保被除数长度大于除数,
// 放大被除数的要求精度的倍数,确保整数计算能保留希望的小数部分
// 还原小数点,输出要求的精度,多余部分截断
if (!isNumeric(decimal1)) throw new ArgumentException("Invalid argument");
if (!isNumeric(decimal2)) throw new ArgumentException("Invalid argument"); //判断负号
int s1 = decimal1.IndexOf('-');
if (s1 >= ) decimal1 = decimal1.Replace("-", ""); //判断负号
int s2 = decimal2.IndexOf('-');
if (s2 >= ) decimal2 = decimal2.Replace("-", ""); int sign = s1 + s2; //=-2都是负数;=-1一正一负;=0都是正数;>0非法数字 int decimalpartlength1 = ;
int decimalpartlength2 = ;
int integerpartlength1 = ;
int integerpartlength2 = ; int maxscale = ;
BigInteger bi1;
BigInteger bi2; //检查小数部分长度
int pointIdx1 = decimal1.IndexOf('.');
if (pointIdx1 >= )
{
decimalpartlength1 = decimal1.Length - pointIdx1 - ; //得到小数部分长度
integerpartlength1 = pointIdx1 == ? : pointIdx1; //得到整数部分长度,考虑小数点在第一位的情况
}
else
{
integerpartlength1 = decimal1.Length; //得到整数部分长度
} //检查小数部分长度
int pointIdx2 = decimal1.IndexOf('.');
if (pointIdx2 >= )
{
decimalpartlength2 = decimal2.Length - pointIdx2 - ; //得到小数部分长度
integerpartlength2 = pointIdx2 == ? : pointIdx2; //得到整数部分长度,考虑小数点在第一位的情况
}
else
{
integerpartlength2 = decimal2.Length; //得到整数部分长度
} decimal1=decimal1.Replace(".", "");
decimal2=decimal2.Replace(".", ""); //对齐小数部分
if (decimalpartlength1 < decimalpartlength2)
{
decimal1 = decimal1 + new string('', decimalpartlength2 - decimalpartlength1);
}
if (decimalpartlength2 < decimalpartlength1)
{
decimal2 = decimal2 + new string('', decimalpartlength1 - decimalpartlength2);
} bi1 = BigInteger.Parse(decimal1);
bi2 = BigInteger.Parse(decimal2); if (bi2.ToString() == "") throw new DivideByZeroException("DivideByZeroError"); //throw new DivideByZeroException("DivideByZeroError") int rightpos = ; //计算从右边数小数点的位置,用于还原小数点
int pows = integerpartlength2 - integerpartlength1;
if (pows >= )
{
bi1 = bi1 * BigInteger.Pow(, pows + ); //放大被除数,确保大于除数
rightpos += pows + ;
} //确定小数位的精度
maxscale = Math.Max(decimalpartlength1, decimalpartlength2);
if (CustomScale < )
{
CustomScale = maxscale; //CustomScale<0,表示精度由参数决定
}
else
{
maxscale = Math.Max(maxscale, CustomScale); //得到最大的小数位数
} bi1 = bi1 * BigInteger.Pow(, maxscale); //放大被除数,确保整数除法之后,能保留小数部分
rightpos += maxscale; BigInteger d = bi1 / bi2; //注意整数除法的特点:会丢掉小数部分
string result = d.ToString(); if (rightpos > result.Length)
{
result = "0." + new string('', rightpos - result.Length) + result; //小数点后面的0补上,再还原小数点
}
else
{
result = result.Insert(result.Length - rightpos, "."); //还原小数点
if (result.StartsWith(".")) result = "" + result; //补上个位的0
} //超出精度截断
if (rightpos > CustomScale) result = result.Substring(, result.Length - (rightpos - CustomScale));
//还原正负号
if (sign == -) result = "-" + result;
return result;
} /// <summary>
/// 判断字符串是不是数字:不能有两个小数点、负号只能在最前面、除了小数点和负号,只能是数字。
/// </summary>
private static bool isNumeric(string strInput)
{
char[] ca = strInput.ToCharArray();
int pointcount = ;
for (int i = ; i < ca.Length; i++)
{
if ((ca[i] < '' || ca[i] > '') && ca[i] != '.' && ca[i] != '-') return false;
if ((ca[i] == '-') && (i != )) return false; if (ca[i] == '.') pointcount++;
}
if (pointcount > ) return false;
return true;
}

如果需要快速的大数类,可以看看这个http://www.cnblogs.com/skyivben/archive/2008/07/25/1251697.html,

下载链接  https://bitbucket.org/ben.skyiv/biginteger

用C# BigInteger实现的BigDecimal类,终于可以直接做四则运算了。的更多相关文章

  1. Java大数处理类:BigInteger类和BigDecimal类

    当我们要处理非常大的数据时,平常用的数据类型已不足以表示,在Java中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,这两个类在理论上只要计算机内存足够大就能够表示无线 ...

  2. BIgInteger类和BigDecimal类的理解

    第一部分: 这两个类位于java.math包内,要使用它们必须在类前面引用该包:import java.math.BigInteger;和import java.math.BigDecimal; Bi ...

  3. Java学习笔记26(Math类、Arrays类、BigInteger类、BigDecimal类)

    Math类:数学工具类,做一些数学计算,开方,对数,三角函数等 所有方法都是静态方法,不需要建立对象,直接用类名调用即可 示例: 这里写几个在日常开发中会用到的,比如三角函数之类的平时不会用到,了解即 ...

  4. 14-03 java BigInteger类,BigDecimal类,Date类,DateFormat类,Calendar类

    BigInteger类 发 package cn.itcast_01; import java.math.BigInteger; /* * BigInteger:可以让超过Integer范围内的数据进 ...

  5. BigInteger 类 和 BigDecimal 类

    一 .BigInteger BigInteger类在计算和处理任意大小的整数方面是很有用的. BigInteger 任意大的整数,原则上是,只要你的计算机的内存足够大,可以有无限位的. BigInte ...

  6. 算法笔记--java的BigInteger类及BigDecimal类

    引包:import java.math.*; BigInteger类: 可以使用构造方法:public BigInteger(String val),或者valueOf(int)函数,如: BigIn ...

  7. 正则表达式、Calendar类、SimpleDateFormat类、Date类、BigDecimal类、BigInteger类、System类、Random类、Math类(Java基础知识十四)

    1.正则表达式的概述和简单使用 * A:正则表达式(一个字符串,是规则)     * 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串.其实就是一种规则.有自己特殊的应用. * B: ...

  8. BigInteger、BigDecimal类的使用详解

    我们都知道在java里边long算是存储长度比较大的了,但是如果有很大的数我们应该怎么处理呢,不用怕,java还为我们准备了一个BigInteger的类,那么这个类到底能存储多大的数呢,这个一时还真不 ...

  9. Java学习——BigInteger类和BigDecimal类

    Java学习——BigInteger类和BigDecimal类 摘要:本文主要学习了用于大数字运算的BigInteger类和BigDecimal类. 部分内容来自以下博客: https://www.c ...

随机推荐

  1. Linux系统网络文件配置

    /etc  一.修改配置文档(需要重启网络配置,永远生效) 1.修改IP地址[MariaDB@db1]$ vi /etc/sysconfig/network-scripts/ifcfg-eth0DEV ...

  2. NumPy 中的集合运算

    怎样快速找出两个数组中相同的元素? numpy.isin(element,test_elements,assume_unique = False,invert = False ) 计算test_ele ...

  3. 修改Windows默认远程端口号

    1.定位注册表,[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp],右侧修改 ...

  4. jQuery -- 光阴似箭(五):AJAX 方法

    jQuery -- 知识点回顾篇(五):AJAX 方法 1. $.ajax 方法:用于执行 AJAX(异步 HTTP)请求. <!DOCTYPE html> <html> &l ...

  5. 《Java大学教程》—第6章 类和对象

    6.2 对象:结构化编程-->数据-->封装(聚合,信息隐藏)-->对象(方法及其操作的数据都聚合在一个单元中,作为更高层的组织单元)-->类(创建对象的模板)6.3 类:*  ...

  6. docker pull下载镜像报错Get https://registry-1.docker.io/v2/library/centos/manifests/latest:..... timeout

    使用docker pull从镜像仓库拉取镜像时报错如下:[root@docker-registry ~]# docker pull centosUsing default tag: latestTry ...

  7. 寒假训练——搜索 K - Cycle

    A tournament is a directed graph without self-loops in which every pair of vertexes is connected by ...

  8. 缓存数据库Memcache

    为什么用缓存数据库 MySQL:将数据存储在磁盘上,数据写入读取相对较慢 Memcached:将数据存在内存中的数据库,数据读写都快,但是数据容易丢失 数据存储,数据仓库选择MySQL这种磁盘的数据库 ...

  9. mac下安装redis详细步骤

    Linux下安装redis也可以参照下面的步骤哦!!!! 1.到官网上下载redis,我下载的版本是redis-3.2.5.tar 官网地址:http://redis.io/ 2.将下载下来的tar. ...

  10. 用powershell实现自动化操作

    每天登录OA太繁琐,公司OA又只允许用IE,本身写chrome扩展水平也不高,更搞不懂selenium 既然是windows下工作,当然还得微软的东东.研究了几天,才发现用powershell就很方便 ...