C#实现的分数结构(编辑中)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace RainbowFraction
{
    public struct RainbowFraction : IComparable,  IComparable<RainbowFraction>, IEquatable<RainbowFraction>
    {
        #region 字段
        private long _numerator;
        private long _denominator;
        #endregion

        #region 属性
        /// <summary>
        /// 分子
        /// </summary>
        public long Numerator
        {
            set
            {//分母分子不能同为负
                if (value * _denominator >= 0)
                {
                    _numerator = Math.Abs(value);
                    _denominator = Math.Abs(_denominator);
                }
                else
                {
                    _numerator = Math.Abs(value) * -1;
                    _denominator = Math.Abs(_denominator);
                }
            }
            get { return _numerator; }
        }
        /// <summary>
        /// 分母
        /// </summary>
        public long Denominator
        {
            get { return _denominator; }
            set
            {//分母分子不能同为负
                if (value != 0)
                {
                    if (_numerator * value >= 0)
                    {
                        _numerator = Math.Abs(_numerator);
                        _denominator = Math.Abs(value);
                    }
                    else
                    {
                        _numerator = Math.Abs(_numerator) * -1;
                        _denominator = Math.Abs(value);
                    }
                }
                else
                {
                    throw new RainbowFractionException("分母不可为0.");
                }
            }
        }
        /// <summary>
        /// 值
        /// </summary>
        public double Value
        {
            get { return (double)Numerator / (double)Denominator; }
        }
        #endregion

        #region 构造
        /// <summary>
        /// 以分子分母构造
        /// </summary>
        /// <param name="srcNum"></param>
        /// <param name="srcDen"></param>
        public RainbowFraction(long srcNum, long srcDen)
        {
            if (srcDen == 0)
            {
                throw new RainbowFractionException("分母不可为0");
            }
            if (srcNum * srcDen >= 0)
            {
                _numerator = Math.Abs(srcNum);
                _denominator = Math.Abs(srcDen);
            }
            else
            {
                _numerator = Math.Abs(srcNum) * -1;
                _denominator = Math.Abs(srcDen);
            }
        }
        /// <summary>
        /// 以double构造
        /// </summary>
        /// <param name="srcDouble"></param>
        public RainbowFraction(double srcDouble)
        {
            _numerator = 0;
            _denominator = 1;
            RainbowFraction tmp = ToRainbowFraction(srcDouble);
            _numerator = tmp.Numerator;
            _denominator = tmp.Denominator;
        }
        /// <summary>
        /// 以字符串构造
        /// </summary>
        /// <param name="srcString"></param>
        public RainbowFraction(string srcString)
        {
            _numerator = 0;
            _denominator = 1;
            RainbowFraction tmp = ToRainbowFraction(srcString);
            _numerator = tmp.Numerator;
            _denominator = tmp.Denominator;
        }
        #endregion

        #region 方法
        /// <summary>
        /// double to fraction
        /// </summary>
        /// <param name="srcDouble"></param>
        /// <returns></returns>
        public static RainbowFraction ToRainbowFraction(double srcDouble)
        {
            RainbowFraction result = new RainbowFraction();
            try
            {
                checked
                {
                    string srcString = srcDouble.ToString();
                    double tmpNum = srcDouble;
                    long tmpDen = 1;
                    while (srcString.IndexOf(‘E‘) > 0)
                    {
                        tmpNum *= 10;
                        tmpDen *= 10;
                        srcString = tmpNum.ToString();
                    }
                    if (srcString.Contains(‘.‘))
                    {
                        int lengthAfterDot = srcString.Split(‘.‘)[1].Length;
                        while (lengthAfterDot > 0)
                        {
                            tmpNum *= 10;
                            tmpDen *= 10;
                            lengthAfterDot--;
                        }
                    }
                    result = new RainbowFraction((long)Math.Round(tmpNum), tmpDen);
                }
            }
            catch (OverflowException)
            {
                throw new RainbowFractionException("转换时发生溢出");
            }
            catch (Exception)
            {
                throw new RainbowFractionException("转换失败");
            }
            return result;
        }
        /// <summary>
        /// string to double
        /// </summary>
        /// <param name="srcString"></param>
        /// <returns></returns>
        public static RainbowFraction ToRainbowFraction(string srcString)
        {
            RainbowFraction result = new RainbowFraction();
            try
            {
                double srcDouble = 0;
                Regex fracRegex = new Regex(@"^\d+\/\d+$");
                if (double.TryParse(srcString, out srcDouble))
                {//形如1.23
                    result = ToRainbowFraction(srcDouble);
                }
                else if (fracRegex.IsMatch(srcString))
                {//形如1/23
                    result = new RainbowFraction(Convert.ToInt64(srcString.Split(‘/‘)[0]), Convert.ToInt64(srcString.Split(‘/‘)[1]));
                }
                else
                {
                    throw new RainbowFractionException("输入字符串有误");
                }
            }
            catch
            {
                throw new RainbowFractionException("转换失败");
            }
            return result;
        }
        /// <summary>
        /// 转化为字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Denominator == 0 ? "NaN" : string.Format("{0}/{1}", Numerator, Denominator);
        }
        #endregion

        #region 接口实现
        public int CompareTo(object obj)
        {
            int result = 0;
            double tmpValue = 0;
            if (obj is string)
            {
                if (this > ToRainbowFraction(obj as string))
                {
                    result = 1;
                }
                else if (this < ToRainbowFraction(obj as string))
                {
                    result = -1;
                }
                else
                {
                    result = 0;
                }
            }
            else if (double.TryParse(obj as string, out tmpValue))
            {
                result = this.Value.CompareTo(tmpValue);
            }
            else
            {
                throw new RainbowFractionException("比较失败");
            }
            return result;
        }
        /// <summary>
        /// 分数比较
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo(RainbowFraction other)
        {
            int result = 0;
            if (this > other)
            {
                result = 1;
            }
            else if (this < other)
            {
                result = -1;
            }
            return result;
        }
        /// <summary>
        /// 分数判等
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public bool Equals(RainbowFraction other)
        {
            return this.Value == other.Value;
        }
        #endregion

        #region 隐式转化
        /// <summary>
        /// double to fraction
        /// </summary>
        /// <param name="srcDouble"></param>
        /// <returns></returns>
        public static implicit operator RainbowFraction(double srcDouble)
        {
            RainbowFraction result = new RainbowFraction(srcDouble);
            return result;
        }
        /// <summary>
        /// fraction to double
        /// </summary>
        /// <param name="srcFrac"></param>
        /// <returns></returns>
        public static implicit operator double(RainbowFraction srcFrac)
        {
            return srcFrac.Value;
        }
        #endregion

        #region 运算符重载
        //一元逻辑运算
        public static RainbowFraction operator -(RainbowFraction srcFrac)
        {
            return new RainbowFraction(srcFrac.Numerator * -1, srcFrac.Denominator);
        }

        //二元逻辑运算
        public static bool operator >(RainbowFraction left, RainbowFraction right)
        {
            return left.Value > right.Value;
        }
        public static bool operator >=(RainbowFraction left, RainbowFraction right)
        {
            return left.Value >= right.Value;
        }
        public static bool operator <(RainbowFraction left, RainbowFraction right)
        {
            return left.Value < right.Value;
        }
        public static bool operator <=(RainbowFraction left, RainbowFraction right)
        {
            return left.Value < right.Value;
        }
        public static bool operator ==(RainbowFraction left, RainbowFraction right)
        {
            return left.Value == right.Value;
        }
        public static bool operator !=(RainbowFraction left, RainbowFraction right)
        {
            return left.Value != right.Value;
        }
        //二元算术运算
        public static RainbowFraction operator +(RainbowFraction left, RainbowFraction right)
        {
            RainbowFraction result = new RainbowFraction();
            result.Denominator = left.Denominator * right.Denominator;
            result.Numerator = left.Numerator * right.Denominator + right.Numerator * left.Denominator;
            return result;
        }
        public static RainbowFraction operator -(RainbowFraction left, RainbowFraction right)
        {
            RainbowFraction result = new RainbowFraction();
            result.Denominator = left.Denominator * right.Denominator;
            result.Numerator = left.Numerator * right.Denominator - right.Numerator * left.Denominator;
            return result;
        }
        public static RainbowFraction operator *(RainbowFraction left, RainbowFraction right)
        {
            RainbowFraction result = new RainbowFraction();
            result.Denominator = left.Denominator * right.Denominator;
            result.Numerator = left.Numerator * right.Numerator;
            return result;
        }
        public static RainbowFraction operator /(RainbowFraction left, RainbowFraction right)
        {
            RainbowFraction result = new RainbowFraction();
            result.Denominator = left.Denominator * right.Numerator;
            result.Numerator = left.Numerator * right.Denominator;
            return result;
        }
        #endregion

    }
    /// <summary>
    /// 分数异常
    /// </summary>
    public class RainbowFractionException : Exception
    {
        public RainbowFractionException(string srcMsg)
            : base(srcMsg)
        {
        }
    }
}

  

时间: 2024-08-07 08:38:41

C#实现的分数结构(编辑中)的相关文章

file结构体中private_data指针的疑惑【转】

本文转载自:http://www.cnblogs.com/pengdonglin137/p/3328984.html hi all and barry, 最近在学习字符设备驱动,不太明白private_data在字符驱动中的作用,我们在 驱动中添加一个设备结构体,然后定义了这个结构体的全局指针变量,接着我们就能在 驱动程序中使用这个指针了.我看到很多驱动程序中都把结构体指针付给private_data, 然后对private_data操作. 为什么要使用private_data,难道仅仅是避免使

结构体中的数据对齐

c语言结构中需要注意的就是数据存储的对齐方式. 对齐的好处:对齐主要是为了方便数据的访问,提高计算机的处理速度,但同时它会浪费内存空间. CPU的优化规则大致是这样的:对于n字节的元素,它的首地址能被n整除,才能获得最好的性能. 对齐的使用原则: 1.一般的基本对齐原则是按着最大的基本类型的长度进行对齐.较小的元素可以组合起来填充一段内存,实现基本的对齐.前提是其满足条件2. 2.结构体中的元素也要满足一定的分布条件,就是元素的存储起始地址要满足能够整除该元素类型的长度. 3.在结构体中存在结构

结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法

结构体中最后一个成员为[0]长度数组的用法:这是个广泛使用的常见技巧,常用来构成缓冲区.比起指针,用空数组有这样的优势:(1).不需要初始化,数组名直接就是所在的偏移:(2).不占任何空间,指针需要占用int长度空间,空数组不占任何空间.“这个数组不占用任何内存”,意味着这样的结构节省空间:“该数组的内存地址就和它后面的元素地址相同”,意味着无需初始化,数组名就是后面元素的地址,直接就能当指针使用. 这样的写法最适合制作动态buffer,因为可以这样分配空间malloc(sizeof(struc

libev 中 ev_loop 结构体中的成员变量

1.ev_loop是libev用来描述事件循环的结构体.在libev中的定义比较绕,这里把它摘抄出来,做下注释,方便学习.libev的定义如下 struct ev_loop { ev_tstamp ev_rt_now; #define ev_rt_now ((loop)->ev_rt_now) #define VAR(name,decl) decl; #include "ev_vars.h" #undef VAR }; #include "ev_wrap.h"

页面状态保持机制(编辑中)

在ASPX页面中,每个控件的状态,通过VIEWSTATE进行保持,但前提是必须以回调的方式进行调用.我们的很多页面处理,都是以URL调用的方式进行的,无法使用VIEWSTATE. 在上例的分页处理中,使用了URL参数来传递状态,这种传递方式简单明了,但也存在问题: 1.复杂 2.和其他方式之间的共处存在问题 特别是第二点,在分页中体现得非常明显:既要能通过URL传递,还要允许页面控制,还要能传递新的参数.要实现这一要求,只能借助复杂的处理逻辑来实现了: 这种方式,当页面还有其他参数的时候,就会很

遍历结构体中的变量

public struct Site  {  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 30)]  public string Country;     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]  public string StationNumber;     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]  publi

结构体中函数指针与typedef关键用途(函数指针)

// 结构体函数指针.  #include<stdio.h> //为了代码的移植考虑,一般使用typedef定义函数指针类 ,另一个好处是,减少代码的书写量.  typedef void (*shout)(char *name,int age); typedef struct {  //用指针来存储字符串     char *name;    int age ;    shout personinfo; }person; //类似于c++中类方法的实现,在这里,是为结构体中指针函数提供实现.在

结构体中的位域

在储存信息时,有时并不需要一个字节的空间而是只需要几个二进制位就足够了.因此在C语言中为了节省空间提高效率,因此引出了位域(也叫位段)的概念. 如下代码中: #include<stdio.h> typedef struct Test { char a : 1; char b : 1; char c : 1; }Test; void main() { printf("sizeof(Test) = %d\n",sizeof(Test)); } a,b,c都是字符类型,而每个字符

对于结构体中内存对齐的简单说明

结构体内存对齐的原因: 在运行一个结构体时,编译器需要给结构体中的每个变量成员分配内存空间,如这样一个结构体中 typedef struct A { char c1; int i; int j; }A; 对其内存空间分配问题进行分析,如若不进行内存对齐,它的内存空间是: char类型变量c1占1个字节,紧接着int类型变量i与j分别占4个字节,总有9个字节,在访问时,如图1,访问次数较多:在图2中,总有12个字节空间,虽然浪费了c1后的三个字节空间,访问次数却变少,会很大程度上节省了时间,提高了

浅析网站结构优化中导航系统的设置技巧

站长们,你们对于网站结构优化中导航系统的设置知多少呢?导航系统的设置的好坏对于网站结构的优化有着相当大的影响.咱们的导航做的目标越清晰,越符合用户的体验度.人性化一点来说,网站导航就跟汽车导航的作用差不多,指明目标,所以我们要从两个方面考虑如何导航系统. 从用户的角度来看,第一点用户可能会从任何一个内页进入到咱们的网站,导航系统要做的就是随时清除的让用户知道自己在网站的哪个位置.因为点开多个网站的内页后,用户自己也已经晕了,不知道自己是怎么点进这个页面的.所以,我们在设计的时候最好统一页面的风格