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. CentOS6.5内 Oracle 11GR2静默安装

    一.修改配置文件 1.1.修改/etc/security/limits.conf文件,修改用户的SHELL的限制. 输入命令:vi /etc/security/limits.conf,将下列内容加入该 ...

  2. SQL Server Browser探究

    一.官网关于SQL SERVER Browser服务的解释(谷歌翻译后稍作修改的): https://docs.microsoft.com/en-us/sql/tools/configuration- ...

  3. c/c++ 标准库 set 自定义关键字类型与比较函数

    标准库 set 自定义关键字类型与比较函数 问题:哪些类型可以作为标准库set的关键字类型呢??? 答案: 1,任意类型,但是需要额外提供能够比较这种类型的比较函数. 2,这种类型实现了 < 操 ...

  4. Spring MVC 之请求参数和路径变量

    请求参数和路径变量都可以用于发送值给服务器.二者都是URL的一部分.请求参数采用key=value形式,并用“&”分隔. 例如,下面的URL带有一个名为productId的请求参数,其值为3: ...

  5. 网站出现403 Forbidden

    1, 你在一定时间内过多地访问此网站(一般是用采集程序),被防火墙拒绝访问了 2, 网站域名解析到了空间,但空间未绑定此域名 3, 你的网页脚本文件在当前目录下没有执行权限 4, 服务器繁忙,同一IP ...

  6. 内网ip/公网ip

    ip地址初识: 现在的IP网络使用32位地址,以点分十进制表示,如172.16.0.0.地址格式为:IP地址=网络地址+主机地址 或 IP地址=网络地址+子网地址+主机地址. IP地址类型 最初设计互 ...

  7. C# -- Lambda 表达式的使用

    C# -- Lambda 表达式的使用 Lambda 表达式是作为对象处理的代码块(表达式或语句块). 它可作为参数传递给方法,也可通过方法调用返回. Lambda 表达式是可以表示为委托的代码,或者 ...

  8. AttributeError: 'list' object has no attribute 'keys'

    #encoding=utf-8 import os result = {} if os.path.exists("test.txt"): day_file = open(" ...

  9. About Swift

    Swift is a new programming language for iOS and OS X apps that builds on the best of C and Objective ...

  10. UVA1374-Power Calculus(迭代加深搜索)

    Problem UVA1374-Power Calculus Accept:323  Submit:2083 Time Limit: 3000 mSec  Problem Description  I ...