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. c/c++ 编译器提供的默认6个函数

    c/c++ 编译器提供的默认6个函数 1,构造函数 2,拷贝构造函数 3,析构函数 4,=重载函数 5,&重载函数 6,const&重载函数 #include <iostream ...

  2. 介绍一个比较了各种浏览器对于HTML5 等标准支持程度的网站

    可以选择浏览器种类,版本,比较的功能 网站地址:https://caniuse.com/#comparison

  3. php5.4新功能Traits

    php5.4新功能Traits介绍 1. traits Traits是在5.4中新增的一个用于实现代码重用的方法. php是一种单一继承的语言,我们无法像java一样在一个class中extends多 ...

  4. python——作用域之LEGB规则

    1 变量的作用域 Python是静态作用域,也就是说在Python中,变量的作用域源于它在代码中的位置:在不同的位置,可能有不同的命名空间.命名空间是变量作用域的体现形式. 2 LEGB各自代表的含义 ...

  5. Windows 版本说明,Enterprise、Ultimate、Home、Professional知多少

    关于Windows 的安装光盘版本很多种,很多人不知道选择哪些. Ultimate 旗舰版,VISTA开始有了这个级别,是最全最高级的,一般程序开发的电脑,玩游戏的电脑,建议用它,不过对配置稍有一些要 ...

  6. C# -- 接口 (关键字:interface)

    C#: 接口(关键字:interface) 1.代码(入门举例) class Program { static void Main(string[] args) { Console.WriteLine ...

  7. 【PS技巧】常用概念和功能操作

    常用概念 1.画布大小与图像大小 画布大小是图像背景的大小,即画纸.图像大小是当前编辑的图层的所有对象大小,即画纸上的画. 常用功能操作 1.打开和新建功能 打开图片:Ctrl+O或双击工作区 图片垂 ...

  8. 看Linux 之父是如何定义 Linux?

    看Linux 之父是如何定义 Linux? LINUX是什么? LINUX是一个免费类unix内核,适用于386-AT计算机,附带完整源代码.主要让黑客.计算机科学学生使用,学习和享受.它大部分用C编 ...

  9. Linux之命令进阶

    Linux系统的启动过程 1.开机自检 BIOS2.MBR引导3.GRUB菜单4.加载内核5.运行init进程6.从/etc/inittab读取运行级别7.根据/etc/rc.sysinit 初始化系 ...

  10. 如何给30台centos7服务器分别增加相同的用户

    老大直接给了30台新鲜的生产服务器,要给每一台服务器增加一个用户,密码相同 难道我们要部署一个工具吗?这样对生产环境可能会产生影响,为了保证服务器的新鲜以及节约时间,研究了小半天,终于研究出一个不是很 ...