用C# BigInteger实现的BigDecimal类,终于可以直接做四则运算了。
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类,终于可以直接做四则运算了。的更多相关文章
- Java大数处理类:BigInteger类和BigDecimal类
当我们要处理非常大的数据时,平常用的数据类型已不足以表示,在Java中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,这两个类在理论上只要计算机内存足够大就能够表示无线 ...
- BIgInteger类和BigDecimal类的理解
第一部分: 这两个类位于java.math包内,要使用它们必须在类前面引用该包:import java.math.BigInteger;和import java.math.BigDecimal; Bi ...
- Java学习笔记26(Math类、Arrays类、BigInteger类、BigDecimal类)
Math类:数学工具类,做一些数学计算,开方,对数,三角函数等 所有方法都是静态方法,不需要建立对象,直接用类名调用即可 示例: 这里写几个在日常开发中会用到的,比如三角函数之类的平时不会用到,了解即 ...
- 14-03 java BigInteger类,BigDecimal类,Date类,DateFormat类,Calendar类
BigInteger类 发 package cn.itcast_01; import java.math.BigInteger; /* * BigInteger:可以让超过Integer范围内的数据进 ...
- BigInteger 类 和 BigDecimal 类
一 .BigInteger BigInteger类在计算和处理任意大小的整数方面是很有用的. BigInteger 任意大的整数,原则上是,只要你的计算机的内存足够大,可以有无限位的. BigInte ...
- 算法笔记--java的BigInteger类及BigDecimal类
引包:import java.math.*; BigInteger类: 可以使用构造方法:public BigInteger(String val),或者valueOf(int)函数,如: BigIn ...
- 正则表达式、Calendar类、SimpleDateFormat类、Date类、BigDecimal类、BigInteger类、System类、Random类、Math类(Java基础知识十四)
1.正则表达式的概述和简单使用 * A:正则表达式(一个字符串,是规则) * 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串.其实就是一种规则.有自己特殊的应用. * B: ...
- BigInteger、BigDecimal类的使用详解
我们都知道在java里边long算是存储长度比较大的了,但是如果有很大的数我们应该怎么处理呢,不用怕,java还为我们准备了一个BigInteger的类,那么这个类到底能存储多大的数呢,这个一时还真不 ...
- Java学习——BigInteger类和BigDecimal类
Java学习——BigInteger类和BigDecimal类 摘要:本文主要学习了用于大数字运算的BigInteger类和BigDecimal类. 部分内容来自以下博客: https://www.c ...
随机推荐
- python连接sqlserver数据库
1.准备工作 python3.6连接sqlserver数据库需要引入pymssql模块 pymssql官方:https://pypi.org/project/pymssql/ 没有安装的话需要: pi ...
- VsCode中使用Emmet神器快速编写HTML代码
一.Emmet简述 Emmet (前身为 Zen Coding) 是一个能大幅度提高前端开发效率的一个工具. 在前端开发的过程中,一大部分的工作是写 HTML.CSS 代码.特别是手动编写 HTML ...
- memory 监控 mysql vs percona vs maria
oracle mysql 5.7 在performance_schema 通过以下表展现内存信息.这些表实际engine为performance_schema.这些表数据实际是以数组的形式存储在内存中 ...
- c/c++ const this指针
const this指针 方法列表后面的const是什么含义呢?答案:不可以在方法里修改成员变量 class Test{ public: void fun()const{ //data = 10;// ...
- Mac轻量级服务器http-server
刚想跑个Vue页面,发现我本地没有应用服务器(Tomcat/IIS...) 于是想下载了Tomcat,才发现我没有装JDK,而Mac的JDK下得好久,都下不下来,想想算了. 于是在网上找个轻量级的服务 ...
- orcFile split和读数据原理总结(hive0.13)
http://blog.csdn.net/zhaorongsheng/article/details/72903431 官网关于orcfile的介绍 背景 Hive的rcfile格式已经使用多年,但是 ...
- 一、tars简单介绍 二、tars 安装部署资料准备
1.github地址https://github.com/Tencent/Tars/ 2.tars是RPC开发框架,目前支持c++,java,nodejs,php 3.tars 在腾讯内部已经使用了快 ...
- 并发的HashMap为什么会引起死循环?
转载:http://blog.csdn.net/zhuqiuhui/article/details/51849692 今天研读Java并发容器和框架时,看到为什么要使用ConcurrentHashMa ...
- yum安装提示Another app is currently holding the yum lock; waiting for it to exit...
在Linux系统中使用yum安装软件时,提示yum处于锁定状态 Another app is currently holding the yum lock; waiting for it to exi ...
- P1182 数列分段`Section II`(贪心+二分, 好题)
这道题让我见识了二分的新姿势.本来,我是二分的位置的. 思路:直接二分答案x, 关键是检验函数的写法: 先用前缀和 a[i....], 看满足多少段满足 a[ j ]-a[ i ]<=x; 的注 ...