您的位置:首页 > 其它

浮点数(有限浮点数、无限循环浮点数)的精确表达

2015-11-18 22:27 423 查看
  在计算机中,是否decimal或者float或者double来存储小数是不能得到精确值得。如果你希望能得到精确的计算结果,最好是用分数形式来表示小数。有限小数或者无限循环小数都可以转化为分数。

  例如:

  0.9=9/10

  0.333(3)=1/3

 给定一个小数,它的形式为0.34、0.30、0.33(33)、.....形如这些的小数把它们转化成分数形式(最简分数)。

首先我们先定义一个分数类和小数类

/// <summary>
/// 分数类
/// </summary>
public class Fraction
{
/// <summary>
/// 是否是正数
/// </summary>
private bool _isPlus = false;
/// <summary>
/// 是否是正数
/// </summary>
public bool IsPlus
{
get { return _isPlus; }
set { _isPlus = value; }
}

/// <summary>
/// 分子
/// </summary>
private Int64 _molecule;
/// <summary>
/// 分子
/// </summary>
public Int64 Molecule
{
get { return _molecule; }
set { _molecule = value; }
}

/// <summary>
/// 分母
/// </summary>
private Int64 _denominator;
/// <summary>
/// 分母
/// </summary>
public Int64 Denominator
{
get { return _denominator; }
set
{
if (value != 0)
_denominator = value;
else
{
throw new Exception("分母不能为零");
}
}
}

public Fraction() { }
public Fraction(int molecule, int denominator)
{
this._denominator = denominator;
this._molecule = molecule;
}

public void Show()
{
if (this._isPlus)
Console.WriteLine("分数为:{0}/{1}", this._molecule, this._denominator);
else
Console.WriteLine("分数为:-{0}/{1}", this._molecule, this._denominator);
}

}


/// <summary>
/// 浮点数类
/// </summary>
public class Decimals
{
/// <summary>
/// 是否是整数
/// </summary>
private bool _isPlus = false;
/// <summary>
/// 是否是整数
/// </summary>
public bool IsPlus
{
get { return _isPlus; }
set { _isPlus = value; }
}

/// <summary>
/// 整数部分
/// </summary>
private Int64 _integer;
/// <summary>
/// 整数部分
/// </summary>
public Int64 Integer { get { return _integer; } set { _integer = value; } }

/// <summary>
/// 小数部分
/// </summary>
private Int64 _double;
/// <summary>
/// 小数部分
/// </summary>
public Int64 Dobule { get { return _double; } set { _double = value; } }

/// <summary>
/// 循环部分
/// </summary>
public Int64 _loop;
/// <summary>
/// 循环部分
/// </summary>
public Int64 Loop { get { return _loop; } set { _loop = value; } }

/// <summary>
/// 循环部分
/// </summary>
public bool _isLoop = false;
/// <summary>
/// 循环部分
/// </summary>
public bool IsLoop
{
get { return _isLoop; }
set { _isLoop = value; }
}

/// <summary>
/// 循环浮点数
/// </summary>
/// <param name="integer"></param>
/// <param name="doubles"></param>
/// <param name="loop"></param>
public Decimals(Int64 integer, Int64 doubles, Int64 loop)
{
this._integer = integer;
this._double = doubles;
this._loop = loop;
this.IsLoop = true;
}

/// <summary>
/// 有限浮点数
/// </summary>
/// <param name="integer"></param>
/// <param name="doubles"></param>
public Decimals(Int64 integer, Int64 doubles)
{
this._integer = integer;
this._double = doubles;
this.IsLoop = false;
}

public Decimals() { }

}


判断输入的浮点数是否合法

/// <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();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: