Feedback

C# - Bruch-Klasse

Veröffentlicht von am 11/15/2009
(6 Bewertungen)
Hier ist einmal eine Klasse die Brüche darstellen kann und damit rechnen kann.

Benötigt werden:


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

namespace Fraction
{
    [global::System.Serializable]
    public class DenominatorIsZeroException : Exception
    {
        public DenominatorIsZeroException() { }
        public DenominatorIsZeroException(string message) : base(message) { }
        public DenominatorIsZeroException(string message, Exception inner) : base(message, inner) { }
        protected DenominatorIsZeroException(
          System.Runtime.Serialization.SerializationInfo info,
          System.Runtime.Serialization.StreamingContext context)
            : base(info, context) { }
    }

    public sealed class Fraction :IComparable<Fraction>
    {
        //Zähler
        public long Numerator { get; private set; }
        //Nenner
        public long Denominator { get; private set; }
        public static readonly Fraction Empty = new Fraction(0,1);

        #region ctors
        /// <summary>
        /// Erzeugt einen Bruch der 1/1 darstellt.
        /// </summary>
        public Fraction()
        {
            this.Denominator = 1;
            this.Numerator = 1;
        }
        /// <summary>
        /// Konstruktor zum erzeugen von einem benutzerdefinierten Bruch.
        /// </summary>
        /// <param name="numerator">Der Zähler des Bruches</param>
        /// <param name="denominator">Der Nenner des Bruches</param>
        public Fraction(long numerator,long denominator)
        {
            this.InitializeComponent(numerator, denominator);
        }
        /// <summary>
        /// Erzeugt eine Fractionobjekt aus einer Dezimalzahl.
        /// </summary>
        /// <param name="frac">Die dezimalzahl die zu einem Bruch gemacht werden soll.</param>
        public Fraction(double frac)
        {
            this.InitializeComponent(frac);
        }       
        #endregion
        #region öffentliche Methoden
        /// <summary>
        /// Addiert das aktuelle Bruchobjekt mit einem anderen Bruchobjekt.
        /// </summary>
        /// <param name="frac">Das zu addierende Bruchobjekt</param>
        /// <returns>Gibt die Summe der beiden Bruchobjekte zurück.</returns>
        public Fraction Add(Fraction frac)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Der Bruch darf nicht null sein");

            Fraction newFraction = new Fraction();            
            newFraction.Denominator = this.Denominator * frac.Denominator;
            newFraction.Numerator = (this.Numerator * frac.Denominator) + (frac.Numerator * this.Denominator);
            newFraction.InitializeComponent(newFraction.Numerator, newFraction.Denominator);

            return newFraction;

        }
        /// <summary>
        /// Addition mit einer Ganz Zahl.
        /// </summary>
        /// <param name="number">Die zu addierende Zahl.</param>
        /// <returns>Ein neues Bruchobjekt basierend auf der Summe des alten und der übergebenen Ganzzahl.</returns>
        public Fraction Add(long number)
        {
            Fraction newFraction = new Fraction(number, 1);
            return this.Add(newFraction);
        }
        public Fraction Add(double number)
        {
            Fraction newFraction = new Fraction(number);
            return this.Add(newFraction);


        }
        /// <summary>
        ///  Subtrahiert das aktuelle Bruchobjekt mit einem anderen Bruchobjekt.
        /// </summary>
        /// <param name="frac">Das zu subtrahierende Bruchobjekt.</param>
        /// <returns>Die Differenz der beiden Bruchobjekte.</returns>
        public Fraction Substract(Fraction frac)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Der Bruch darf nicht null sein");

            Fraction newFraction = new Fraction();
            newFraction.Denominator = this.Denominator * frac.Denominator;
            newFraction.Numerator = (this.Numerator * frac.Denominator) - (frac.Numerator * this.Denominator);
            newFraction.InitializeComponent(newFraction.Numerator, newFraction.Denominator);

            return newFraction;
        }
        public Fraction Substract(long number)
        {
            Fraction newFraction = new Fraction(number, 1);
            return this.Substract(newFraction);
        }
        public Fraction Substract(double number)
        {
            return this.Substract(new Fraction(number));
        }
        /// <summary>
        ///  Multipliziert das aktuelle Bruchobjekt mit einem anderen Bruchobjekt.
        /// </summary>
        /// <param name="frac">Das zu multiplizierende Bruchobjekt.</param>
        /// <returns>Das Produkt der beiden Bruchobjekte.</returns>
        public Fraction Multiplie(Fraction frac)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Der Bruch darf nicht null sein");

            return new Fraction(this.Numerator * frac.Numerator, this.Denominator * frac.Denominator);
        }
        public Fraction Multiplie(long number)
        {
            Fraction newFraction = new Fraction(number, 1);
            return this.Multiplie(newFraction);
        }
        public Fraction Multiplie(double number)
        {
            return this.Multiplie(new Fraction(number));
        }
        /// <summary>
        ///  Dividiert das aktuelle Bruchobjekt mit einem anderen Bruchobjekt.
        /// </summary>
        /// <param name="frac">Das zu dividierende Bruchobjekt.</param>
        /// <returns>Der Quotient der beiden Bruchobjekte.</returns>
        public Fraction Divide(Fraction frac)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Der Bruch darf nicht null sein");

            return new Fraction(this.Numerator * frac.Denominator, this.Denominator * frac.Numerator);
        }
        public Fraction Divide(long number)
        {
            Fraction frac = new Fraction(number, 1);
            return this.Divide(frac);
        }
        public Fraction Divide(double number)
        {
            return this.Divide(new Fraction(number));
        }

        public double ToDouble()
        {
            return (Convert.ToDouble(this.Numerator) / Convert.ToDouble(this.Denominator));
        }
        #endregion
        #region private Methoden
        private void InitializeComponent(long numerator, long denominator)
        {
            if (denominator == 0)
                throw new DenominatorIsZeroException("Der Nenner darf nicht '0' sein");

            //den größten gemeinsamen teiler berechnen
            long greatestCommonDivider = this.GreatestCommonDivider(numerator,denominator);
            this.Denominator = denominator / greatestCommonDivider;
            this.Numerator = numerator / greatestCommonDivider;
        }
        private void InitializeComponent(double number)
        {
            double tempNumber = number;
            int counter = 0;
            //solange wie es keine Ganzahl ist, multiplizieren wir die dezimalzahl mit ihrer basis also 10
            while (tempNumber % 1 != 0)
            {

                tempNumber *= 10;
                //erhöhen gleichzeitig einen counter wie oft wir das gemacht haben
                //dadurch merken wir uns die nachkommastellen
                counter++;
            }
            this.Numerator = (long)tempNumber;
            //wir potenzieren unsere nachkommastellen mit 10 um eine relation zwischen zähler und nenner zu erschaffen
            //bei 0.5 -> 5/(10^1)
            this.Denominator = (long)Math.Pow(10, counter);
            this.InitializeComponent(this.Numerator, this.Denominator);
        }
        private long GreatestCommonDivider(long numerator, long denominator)
        {
            //zähler und nenner auf absolute ebene bringen
            long tempNumerator = Math.Abs(numerator);
            long tempDenominator = Math.Abs(denominator);

            if (tempNumerator == 0)
                return tempDenominator;

            while (tempDenominator != 0)
            {
                if (tempNumerator > tempDenominator)
                    tempNumerator -= tempDenominator;
                else
                    tempDenominator -= tempNumerator;
            }
            return tempNumerator;
        }
        #endregion
        #region ToString()
        /// <summary>
        /// Erstellt eine Standardausgabe ála Zähler/Nenner.
        /// </summary>
        /// <returns>Gibt den Bruch in Standardformatierung zurück.</returns>
        public override string ToString()
        {
            return this.Numerator.ToString() + "/" + this.Denominator.ToString();
        }
        /// <summary>
        /// Erzeugt eine Benutzerdefinierte Ausgabe
        /// </summary>
        /// <param name="format">Das Benutzerdefinierte Format. Beispiele sind "-","/","d".</param>
        /// <returns></returns>
        public string ToString(string format)
        {
            if(format == null)
                throw new ArgumentNullException("format","Es muss ein Format angegeben werden");

            switch (format)
            {
                case "-":
                        StringBuilder sb = new StringBuilder();
                        //zaehler einfügen
                        sb.AppendLine(this.Numerator.ToString());
                        //größtes element bestimmen über die string.Length eigenschaft
                        long maxCountOfFractionBar = Math.Max(this.Denominator.ToString().Length, this.Numerator.ToString().Length);
                        //genauso viele Striche einfügen
                        for (long i = 0; i < maxCountOfFractionBar; i++)
                            sb.Append("-");
                        sb.AppendLine();
                        //und den Nenner einfügen
                        sb.AppendLine(this.Denominator.ToString());

                        return sb.ToString();
                case "/":
                        return this.ToString();
               
                default:
                        return this.ToString();
            }


        }
        #endregion
        #region IComparable<Fraction>
        public int CompareTo(Fraction other)
        {
            return this.ToDouble().CompareTo(other.ToDouble());
        }
        #endregion

        #region Operatoren
        #region explicite und implicte Operatoren
        public static implicit operator Fraction(long number)
        {
            return new Fraction(number);
        }
        public static implicit operator Fraction(double number)
        {
            return new Fraction(number);
        }
        #endregion
        #region Binärer Operator+
        public static Fraction operator +(Fraction frac, Fraction otherFrac)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Bruchobjekt darf nicht 'null' sein.");
            return frac.Add(otherFrac);
        }
        public static Fraction operator +(Fraction frac, long number)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Bruchobjekt darf nicht 'null' sein.");

            return frac.Add(number);
        }
        public static Fraction operator +(Fraction frac, double number)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Bruchobjekt darf nicht 'null' sein.");

            return frac.Add(number);
        }
        #endregion
        #region Binärer Operator -
        public static Fraction operator -(Fraction frac, Fraction otherFrac)
        {
             if (frac == null)
                throw new ArgumentNullException("frac", "Bruchobjekt darf nicht 'null' sein.");
            return frac.Substract(otherFrac);
        }
        public static Fraction operator-(Fraction frac,long number)
        {
             if (frac == null)
                throw new ArgumentNullException("frac", "Bruchobjekt darf nicht 'null' sein.");

            return frac.Substract(number);
        }
        public static Fraction operator-(Fraction frac,double number)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Bruchobjekt darf nicht 'null' sein.");

            return frac.Substract(number);

        }

        #endregion
        #region Binärer Operator *
        public static Fraction operator *(Fraction frac, Fraction otherFrac)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Bruchobjekt darf nicht 'null' sein.");
            return frac.Multiplie(otherFrac);
        }
        public static Fraction operator *(Fraction frac, long number)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Bruchobjekt darf nicht 'null' sein.");

            return frac.Multiplie(number);
        }
        public static Fraction operator *(Fraction frac, double number)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Bruchobjekt darf nicht 'null' sein.");
            return frac.Multiplie(number);
        }
        #endregion
        #region Binärer Operator /
        public static Fraction operator /(Fraction frac, Fraction otherFrac)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Bruchobjekt darf nicht 'null' sein.");
            return frac.Divide(otherFrac);
        }
        public static Fraction operator /(Fraction frac, long number)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Bruchobjekt darf nicht 'null' sein.");
            return frac.Divide(number);
        }
        public static Fraction operator /(Fraction frac, double number)
        {
            if (frac == null)
                throw new ArgumentNullException("frac", "Bruchobjekt darf nicht 'null' sein.");
            return frac.Divide(number);
        }
        #endregion
        #endregion
    }
}

Abgelegt unter Bruch, Fraction, Irrationale Zahlen, Mathe.

3 Kommentare zum Snippet

Christopher Kk schrieb am 11/17/2009:
Keine Meinungen?Kritiken(konstruktiv)?Bewertungen?
Sperneder Patrick schrieb am 11/17/2009:
Kannst du mal ein Beispiel angeben wie man das verwenden kann ?
Danke.
Christopher Kk schrieb am 11/17/2009:
Na klar:

Fraction f = new Fraction()//Ctor 1/1 wird aufgerufen
Fraction f = new Fraction(1,3) //Es entsteht der Bruch 1/3
Fraction f = new Fraction(0.5) //Es entsteht 1/2
Fraction f = new Fraction(12) //Es entsteht 12/1
Fraction f = 0.2; //implizier Cast operator wird aufgerufen,es entsteht 1/5
Fraction f = 0.5;
Fraction f2 = 0.1;
Fraction f3 = f + f2; //operator + wird aufgerufen. f3 = 6/10
//usw man kann jegliche operatoren anwenden
//auch so etwas
Fraction f +=0.59; //usw...
//NAtürlich kann man auch explizit die Add,Substract,Divide,Multiplie Methoden aufrufen die wiederum überladen wurden

Noch irgendwelche Beispiele die gewünscht wären?
 

Logge dich ein, um hier zu kommentieren!