1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
|
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
}
}
|