用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 ...
随机推荐
- IPerf——网络测试工具介绍与源码解析(4)
上篇随笔讲到了TCP模式下的客户端,接下来会讲一下TCP模式普通场景下的服务端,说普通场景则是暂时不考虑双向测试的可能,毕竟了解一项东西还是先从简单的情况下入手会快些. 对于服务端,并不是我们认为的直 ...
- python3编写网络爬虫20-pyspider框架的使用
二.pyspider框架的使用 简介 pyspider是由国人binux 编写的强大的网络爬虫系统 github地址 : https://github.com/binux/pyspider 官方文档 ...
- Windows Live Writer 2012在Blogjava管理和发布博客
下载Windows Live Writer 2012的完整版本(wlsetup-all.exe),安装的时候减少网络下载消耗的时间.注:有些平台可能还需要下载DotNet3.5(dotnetfx35. ...
- JavaScrip 入门第一课
一.代码引入的三种方式 1.直接在head中书写 在head标签里面可以写,在body标签里面也可以写,放到head标签里面和放到body标签里面到底有什么区别,我们后续在讲~ <head> ...
- 【Teradata Utility】系统工具使用
List two ways in which a system utility can be started. Explain how to use the following utilities t ...
- HTTP Health Checks
This article describes how to configure and use HTTP health checks in NGINX Plus and open source NGI ...
- linux学习笔记整理(六)
第七章 Centos7-文件权限管理本节所讲内容:7.1文件的基本权限:r w x (UGO)7.2文件的特殊权限:suid sgid sticky和文件扩展权限ACL7.3实战:创建一个让root都 ...
- google colab 使用指南
重启colab !kill - - 输出ram信息 !cat /proc/meminfo 输出cpu信息 !cat /proc/cpuinfo 更改工作文件夹 一般,当你运行下面的命令: !ls 你会 ...
- day1-pycharm使用
1.Ctrl+滑轮 字体大小 2.改变字体大小 3.开头模板 4.多行注释 ctrl+? 5.切换Python版本解释器
- 获取数值型数组中大于60的元素个数,给数值型数组中不足60分的加20分。(数组,for循环,if条件判断语句)
package com.Summer_0420.cn; /** * @author Summer * 获取数值型数组中大于60的元素个数 * 给数值型数组中不足60分的加20分 */ public c ...