在计算机中,是否decimal或者float或者double来存储小数是不能得到精确值得。如果你希望能得到精确的计算结果,最好是用分数形式来表示小数。有限小数或者无限循环小数都可以转化为分数。
例如:
0.9=9/10
0.333(3)=1/3
给定一个小数,它的形式为0.34、0.30、0.33(33)、.....形如这些的小数把它们转化成分数形式(最简分数)。
首先我们先定义一个分数类和小数类
1 /// <summary> 2 /// 分数类 3 /// </summary> 4 public class Fraction 5 { 6 /// <summary> 7 /// 是否是正数 8 /// </summary> 9 private bool _isPlus = false; 10 /// <summary> 11 /// 是否是正数 12 /// </summary> 13 public bool IsPlus 14 { 15 get { return _isPlus; } 16 set { _isPlus = value; } 17 } 18 19 /// <summary> 20 /// 分子 21 /// </summary> 22 private Int64 _molecule; 23 /// <summary> 24 /// 分子 25 /// </summary> 26 public Int64 Molecule 27 { 28 get { return _molecule; } 29 set { _molecule = value; } 30 } 31 32 /// <summary> 33 /// 分母 34 /// </summary> 35 private Int64 _denominator; 36 /// <summary> 37 /// 分母 38 /// </summary> 39 public Int64 Denominator 40 { 41 get { return _denominator; } 42 set 43 { 44 if (value != 0) 45 _denominator = value; 46 else 47 { 48 throw new Exception("分母不能为零"); 49 } 50 } 51 } 52 53 public Fraction() { } 54 public Fraction(int molecule, int denominator) 55 { 56 this._denominator = denominator; 57 this._molecule = molecule; 58 } 59 60 public void Show() 61 { 62 if (this._isPlus) 63 Console.WriteLine("分数为:{0}/{1}", this._molecule, this._denominator); 64 else 65 Console.WriteLine("分数为:-{0}/{1}", this._molecule, this._denominator); 66 } 67 68 69 70 71 }
1 /// <summary> 2 /// 浮点数类 3 /// </summary> 4 public class Decimals 5 { 6 /// <summary> 7 /// 是否是整数 8 /// </summary> 9 private bool _isPlus = false; 10 /// <summary> 11 /// 是否是整数 12 /// </summary> 13 public bool IsPlus 14 { 15 get { return _isPlus; } 16 set { _isPlus = value; } 17 } 18 19 20 /// <summary> 21 /// 整数部分 22 /// </summary> 23 private Int64 _integer; 24 /// <summary> 25 /// 整数部分 26 /// </summary> 27 public Int64 Integer { get { return _integer; } set { _integer = value; } } 28 29 /// <summary> 30 /// 小数部分 31 /// </summary> 32 private Int64 _double; 33 /// <summary> 34 /// 小数部分 35 /// </summary> 36 public Int64 Dobule { get { return _double; } set { _double = value; } } 37 38 /// <summary> 39 /// 循环部分 40 /// </summary> 41 public Int64 _loop; 42 /// <summary> 43 /// 循环部分 44 /// </summary> 45 public Int64 Loop { get { return _loop; } set { _loop = value; } } 46 47 /// <summary> 48 /// 循环部分 49 /// </summary> 50 public bool _isLoop = false; 51 /// <summary> 52 /// 循环部分 53 /// </summary> 54 public bool IsLoop 55 { 56 get { return _isLoop; } 57 set { _isLoop = value; } 58 } 59 60 /// <summary> 61 /// 循环浮点数 62 /// </summary> 63 /// <param name="integer"></param> 64 /// <param name="doubles"></param> 65 /// <param name="loop"></param> 66 public Decimals(Int64 integer, Int64 doubles, Int64 loop) 67 { 68 this._integer = integer; 69 this._double = doubles; 70 this._loop = loop; 71 this.IsLoop = true; 72 } 73 74 /// <summary> 75 /// 有限浮点数 76 /// </summary> 77 /// <param name="integer"></param> 78 /// <param name="doubles"></param> 79 public Decimals(Int64 integer, Int64 doubles) 80 { 81 this._integer = integer; 82 this._double = doubles; 83 this.IsLoop = false; 84 } 85 86 87 public Decimals() { } 88 89 }
判断输入的浮点数是否合法
/// <summary> /// 验证是否为满足要求的浮点数 /// </summary> /// <param name="number"></param> /// <returns></returns> static bool IsDouble(string number) { string[] regexArray = { @"^[1-9]d*.d*(d*|(d+))$" , @"^0.d*(d*|(d+))$", @"^-[1-9]d*.d*(d*|(d+))$", @"^-0.d*(d*|(d+))$"}; bool isResult = false; foreach (string regexString in regexArray) { Regex regex = new Regex(regexString); if (regex.IsMatch(number)) { isResult = true; break; } } return isResult; }
验证是否是循环浮点数
/// <summary> /// 是否为循环浮点数 /// </summary> /// <param name="number"></param> /// <returns></returns> static bool IsLoopDecimal(string number) { string[] regexArray = { @"^[1-9]d*.d*(d+)$" , @"^0.d*(d+)$", @"^-[1-9]d*.d*(d+)$", @"^-0.d*(d+)$"}; bool isReuslt = false; foreach(string regexString in regexArray) { Regex regex = new Regex(regexString); if (regex.IsMatch(number)) { isReuslt = true; break; } } return isReuslt; }
判断是否是正数
/// <summary> /// 判断整数还是正数 /// </summary> /// <param name="number"></param> /// <returns></returns> static bool IsPlus(string number) { string[] regexArray = { @"^[1-9]d*.d*(d*|(d+))$", @"^0.d*(d*|(d+))$"}; bool isResult = false; foreach (string regexString in regexArray) { Regex regex = new Regex(regexString); if (regex.IsMatch(number)) { isResult = true; break; } } return isResult; }
把输入数据转化为浮点数对象
/// <summary> /// 把输入数据转化为浮点数对象 /// </summary> /// <param name="number"></param> /// <returns></returns> static Decimals GetDecimals(string number) { Decimals decimals = null; if (IsLoopDecimal(number)) { #region 循环小数分解部分 decimals = new Decimals(); decimals.IsLoop = true; Regex regexLoop = new Regex(@"^[1-9]d*.");//(d+) string value = regexLoop.Match(number).Groups[0].Value; if (!string.IsNullOrEmpty(value)) decimals.Integer = Convert.ToInt64((value.TrimEnd('.'))); else { decimals.Integer = 0; } value = ""; regexLoop = new Regex(@"(d+)"); value = regexLoop.Match(number).Groups[0].Value; if (!string.IsNullOrEmpty(value)) decimals.Loop = Convert.ToInt64(value.TrimStart('(').TrimEnd(')')); value = ""; regexLoop = new Regex(@".d*("); value = regexLoop.Match(number).Groups[0].Value; if (!string.IsNullOrEmpty(value)) decimals.Dobule = Convert.ToInt64(value.TrimStart('.').TrimEnd('(')); else decimals.Dobule = 0; #endregion } else { #region 有限小数分解部分 decimals = new Decimals(); decimals.IsLoop = false; Regex regexLoop = new Regex(@"^[1-9]d*.");//(d+) string value = regexLoop.Match(number).Groups[0].Value; if (!string.IsNullOrEmpty(value)) decimals.Integer = Convert.ToInt64((value.TrimEnd('.'))); else decimals.Integer = 0; value = ""; regexLoop = new Regex(@".d*$"); value = regexLoop.Match(number).Groups[0].Value; if (!string.IsNullOrEmpty(value)) decimals.Dobule = Convert.ToInt64(value.TrimStart('.')); else decimals.Dobule = 0; #endregion } if (IsPlus(number)) decimals.IsPlus = true; else decimals.IsPlus = false; return decimals; }
求最大公约数
/// <summary> /// 求最大公约数 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> static Int64 GetGCD(Int64 x, Int64 y) { if (x < y) return GetGCD(y, x);
if (y == 0)
throw new Exception("0没有最大公约数"); if (x == y) return y; else return GetGCD(y, x - y); }
测试调用
static void Main(string[] args) { while (true) { Console.Write("请输入浮点数(有限小数或者无限循环小数),例如:0.12、0.23(121) :"); string inputNumber = Console.ReadLine(); if (IsDouble(inputNumber)) { Decimals decimals = GetDecimals(inputNumber); Fraction Fraction = GetFraction(decimals); Fraction.Show(); } else { Console.WriteLine("输入格式不正确"); } Console.ReadLine(); } }