Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
RationalNumber.cs
1using System;
2using System.Numerics;
3using System.Reflection;
7
9{
13 public sealed class RationalNumber : FieldElement
14 {
15 private static readonly RationalNumbers associatedField = new RationalNumbers();
16
17 private BigInteger numerator;
18 private BigInteger denominator;
19
25 public RationalNumber(BigInteger Numerator, BigInteger Denominator)
26 {
27 if (Denominator.IsZero)
28 throw new DivideByZeroException();
29
30 if (Denominator.Sign < 0)
31 {
32 this.numerator = -Numerator;
33 this.denominator = -Denominator;
34 }
35 else
36 {
37 this.numerator = Numerator;
38 this.denominator = Denominator;
39 }
40 }
41
46 public RationalNumber(BigInteger Number)
47 {
48 this.numerator = Number;
49 this.denominator = BigInteger.One;
50 }
51
55 public BigInteger Numerator
56 {
57 get => this.numerator;
58 set => this.numerator = value;
59 }
60
64 public BigInteger Denominator
65 {
66 get => this.denominator;
67 set => this.denominator = value;
68 }
69
71 public override string ToString()
72 {
73 return "(" + Expression.ToString(this.numerator) + "/" +
74 Expression.ToString(this.denominator) + ")";
75 }
76
80 public override IField AssociatedField => associatedField;
81
85 public override object AssociatedObjectValue => this;
86
93 {
94 if (Element is RationalNumber Q)
95 return this * Q;
96
97 object Obj = Element.AssociatedObjectValue;
98
99 if (Obj is BigInteger i)
100 return this * i;
101
102 if (Obj is double d)
103 return new DoubleNumber(this.ToDouble() * d);
104
105 if (Obj is Complex z)
106 return new ComplexNumber(this.ToDouble() * z);
107
108 return null;
109 }
110
115 public double ToDouble()
116 {
117 return ((double)this.numerator) / ((double)this.denominator);
118 }
119
127 {
128 if (Left.numerator.IsZero || Right.numerator.IsZero)
129 return RationalNumbers.zero;
130
131 BigInteger gcd1 = BigInteger.GreatestCommonDivisor(Left.numerator, Right.denominator);
132 BigInteger gcd2 = BigInteger.GreatestCommonDivisor(Right.numerator, Left.denominator);
133
134 BigInteger n = BigInteger.Divide(Left.numerator, gcd1) * BigInteger.Divide(Right.numerator, gcd2);
135 BigInteger d = BigInteger.Divide(Left.denominator, gcd2) * BigInteger.Divide(Right.denominator, gcd1);
136
137 return OperationResult(n, d);
138 }
139
140 private static ICommutativeRingWithIdentityElement OperationResult(BigInteger n, BigInteger d)
141 {
142 if (d.IsOne)
143 return new Integer(n);
144 else if (d.Sign < 0)
145 {
146 n = -n;
147 d = -d;
148
149 if (d.IsOne)
150 return new Integer(n);
151 else
152 return new RationalNumber(n, d);
153 }
154 else
155 return new RationalNumber(n, d);
156 }
157
165 {
166 BigInteger gcd2 = BigInteger.GreatestCommonDivisor(Right, Left.denominator);
167
168 BigInteger n = Left.numerator * BigInteger.Divide(Right, gcd2);
169 BigInteger d = BigInteger.Divide(Left.denominator, gcd2);
170
171 return OperationResult(n, d);
172 }
173
181 {
182 return Right * Left;
183 }
184
192 {
193 return Left * new RationalNumber(Right.denominator, Right.numerator);
194 }
195
203 {
204 return Left * new RationalNumber(BigInteger.One, Right);
205 }
206
214 {
215 return new RationalNumber(Left, BigInteger.One) * new RationalNumber(Right.denominator, Right.numerator);
216 }
217
222 public override IRingElement Invert()
223 {
224 if (this.numerator.IsZero)
225 throw new DivideByZeroException();
226
227 return OperationResult(this.denominator, this.numerator);
228 }
229
236 {
237 if (Element is RationalNumber Q)
238 return this + Q;
239
240 object Obj = Element.AssociatedObjectValue;
241
242 if (Obj is BigInteger i)
243 return this + i;
244
245 if (Obj is double d)
246 return new DoubleNumber(this.ToDouble() + d);
247
248 if (Obj is Complex z)
249 return new ComplexNumber(this.ToDouble() + z);
250
251 return null;
252 }
253
261 {
262 BigInteger n = Left.numerator * Right.denominator + Right.numerator * Left.denominator;
263 BigInteger d = Right.denominator * Left.denominator;
264
265 BigInteger gcd = BigInteger.GreatestCommonDivisor(n, d);
266
267 return OperationResult(BigInteger.Divide(n, gcd), BigInteger.Divide(d, gcd));
268 }
269
277 {
278 BigInteger n = Left.numerator + Right * Left.denominator;
279 BigInteger gcd = BigInteger.GreatestCommonDivisor(n, Left.denominator);
280
281 return OperationResult(BigInteger.Divide(n, gcd), BigInteger.Divide(Left.denominator, gcd));
282 }
283
291 {
292 return Right + Left;
293 }
294
302 {
303 return Left + new RationalNumber(-Right.numerator, Right.denominator);
304 }
305
313 {
314 return Left + new RationalNumber(-Right, BigInteger.One);
315 }
316
324 {
325 return new RationalNumber(Left, BigInteger.One) + new RationalNumber(-Right.numerator, Right.denominator);
326 }
327
332 public override IGroupElement Negate()
333 {
334 return new RationalNumber(-this.numerator, this.denominator);
335 }
336
338 public override bool Equals(object obj)
339 {
340 if (!(obj is IElement E))
341 return false;
342
343 if (E is RationalNumber Q)
344 {
345 if (this.numerator.IsZero)
346 return Q.numerator.IsZero;
347 else
348 return this.numerator * Q.denominator == Q.numerator * this.denominator;
349 }
350
351 object Obj = E.AssociatedObjectValue;
352
353 if (Obj is BigInteger i)
354 return this.numerator == i * this.denominator;
355
356 if (Obj is double d)
357 return this.ToDouble() == d;
358
359 if (Obj is Complex z)
360 return this.ToDouble() == z;
361
362 return false;
363 }
364
366 public override int GetHashCode()
367 {
368 int Result = this.numerator.GetHashCode();
369 Result ^= Result << 5 ^ this.denominator.GetHashCode();
370 return Result;
371 }
372
377
382
389 public override bool TryConvertTo(Type DesiredType, out object Value)
390 {
391 if (DesiredType.GetTypeInfo().IsAssignableFrom(typeof(RationalNumber).GetTypeInfo()))
392 {
393 Value = this;
394 return true;
395 }
396 else
397 {
398 double d = this.ToDouble();
399
400 if (DesiredType == typeof(byte))
401 {
402 if (d >= byte.MinValue && d <= byte.MaxValue)
403 {
404 Value = (byte)d;
405 return true;
406 }
407 }
408 else if (DesiredType == typeof(decimal))
409 {
410 Value = (decimal)d;
411 return true;
412 }
413 else if (DesiredType == typeof(double))
414 {
415 Value = (double)d;
416 return true;
417 }
418 else if (DesiredType == typeof(short))
419 {
420 if (d >= short.MinValue && d <= short.MaxValue)
421 {
422 Value = (short)d;
423 return true;
424 }
425 }
426 else if (DesiredType == typeof(int))
427 {
428 if (d >= int.MinValue && d <= int.MaxValue)
429 {
430 Value = (int)d;
431 return true;
432 }
433 }
434 else if (DesiredType == typeof(long))
435 {
436 if (d >= long.MinValue && d <= long.MaxValue)
437 {
438 Value = (long)d;
439 return true;
440 }
441 }
442 else if (DesiredType == typeof(sbyte))
443 {
444 if (d >= sbyte.MinValue && d <= sbyte.MaxValue)
445 {
446 Value = (sbyte)d;
447 return true;
448 }
449 }
450 else if (DesiredType == typeof(float))
451 {
452 Value = (float)d;
453 return true;
454 }
455 else if (DesiredType == typeof(ushort))
456 {
457 if (d >= ushort.MinValue && d <= ushort.MaxValue)
458 {
459 Value = (ushort)d;
460 return true;
461 }
462 }
463 else if (DesiredType == typeof(uint))
464 {
465 if (d >= uint.MinValue && d <= uint.MaxValue)
466 {
467 Value = (uint)d;
468 return true;
469 }
470 }
471 else if (DesiredType == typeof(ulong))
472 {
473 if (d >= ulong.MinValue && d <= ulong.MaxValue)
474 {
475 Value = (ulong)d;
476 return true;
477 }
478 }
479 }
480
481 return Expression.TryConvert(this, DesiredType, out Value);
482 }
483 }
484}
Base class for all types of elements.
Definition: Element.cs:13
abstract object AssociatedObjectValue
Associated object value.
Definition: Element.cs:46
Base class for all types of field elements.
Definition: FieldElement.cs:10
Class managing a script expression.
Definition: Expression.cs:39
static bool TryConvert(object Value, Type DesiredType, out object Result)
Tries to convert an object Value to an object of type DesiredType .
Definition: Expression.cs:5268
static string ToString(double Value)
Converts a value to a string, that can be parsed as part of an expression.
Definition: Expression.cs:4496
Integer-valued number.
Definition: Integer.cs:13
override bool TryConvertTo(Type DesiredType, out object Value)
Converts the value to a .NET type.
override int GetHashCode()
Calculates a hash code of the element. Hash code.
override IRingElement Invert()
Inverts the element, if possible.
static ICommutativeRingWithIdentityElement operator/(RationalNumber Left, RationalNumber Right)
Divides a rational number with another rational number.
override ICommutativeRingWithIdentityElement One
Returns the identity element of the commutative ring with identity.
override IAbelianGroupElement Add(IAbelianGroupElement Element)
Tries to add an element to the current element.
static ICommutativeRingWithIdentityElement operator*(RationalNumber Left, RationalNumber Right)
Multiplies a rational number with another rational number.
static ICommutativeRingWithIdentityElement operator+(RationalNumber Left, RationalNumber Right)
Adds a rational number with another rational number.
override IField AssociatedField
Associated Field.
RationalNumber(BigInteger Number)
RationalNumber-valued number.
override bool Equals(object obj)
Compares the element to another. If elements are equal.
override object AssociatedObjectValue
Associated object value.
override ICommutativeRingElement Multiply(ICommutativeRingElement Element)
Tries to multiply an element to the current element.
BigInteger Denominator
Denominator
override IAbelianGroupElement Zero
Returns the zero element of the group.
double ToDouble()
Converts rational number to a double-precision floating-point number.
RationalNumber(BigInteger Numerator, BigInteger Denominator)
Rational Number.
override IGroupElement Negate()
Negates the element.
static ICommutativeRingWithIdentityElement operator-(RationalNumber Left, RationalNumber Right)
Subtracts a rational number with another rational number.
Field of rational numbers.
Basic interface for all types of abelian group elements.
Basic interface for all types of commutative ring elements.
Basic interface for all types of commutative ring with identity elements.
Basic interface for all types of elements.
Definition: IElement.cs:20
Basic interface for all types of group elements.
Definition: IGroupElement.cs:9
Basic interface for all types of ring elements.
Definition: IRingElement.cs:10
Basic interface for all types of fields.
Definition: IField.cs:9