-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCircleFraction.cs
102 lines (94 loc) · 6.09 KB
/
CircleFraction.cs
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
using System;
namespace RT.Coordinates
{
/// <summary>Encapsulates a rational number between 0 and 1 that represents a fraction of a circle.</summary>
public struct CircleFraction : IEquatable<CircleFraction>, IComparable<CircleFraction>
{
/// <summary>Numerator.</summary>
public int Numerator { get; private set; }
/// <summary>Denominator.</summary>
public int Denominator { get; private set; }
/// <summary>Constructor.</summary>
public CircleFraction(int numerator, int denominator)
{
if (numerator % denominator == 0)
{
Numerator = 0;
Denominator = 1;
}
else
{
var divisor = gcd(Math.Abs(numerator), Math.Abs(denominator));
Denominator = denominator / divisor;
var num = numerator / divisor;
Numerator = (num % Denominator + Denominator) % Denominator;
}
}
/// <summary>Represents the value 0 (zero).</summary>
public static readonly CircleFraction Zero = new CircleFraction(0, 1);
private static int gcd(int a, int b)
{
while (a != 0 && b != 0)
{
if (a > b)
a %= b;
else
b %= a;
}
return a | b;
}
/// <summary>Addition operator.</summary>
public static CircleFraction operator +(CircleFraction a, CircleFraction b) => new CircleFraction(a.Numerator * b.Denominator + b.Numerator * a.Denominator, a.Denominator * b.Denominator);
/// <summary>Subtraction operator.</summary>
public static CircleFraction operator -(CircleFraction a, CircleFraction b) => new CircleFraction(a.Numerator * b.Denominator - b.Numerator * a.Denominator, a.Denominator * b.Denominator);
/// <summary>Multiplication operator.</summary>
public static CircleFraction operator *(CircleFraction a, CircleFraction b) => new CircleFraction(a.Numerator * b.Numerator, a.Denominator * b.Denominator);
/// <summary>Division operator.</summary>
public static CircleFraction operator /(CircleFraction a, CircleFraction b) => new CircleFraction(a.Numerator * b.Denominator, a.Denominator * b.Numerator);
/// <summary>Less-than comparison operator.</summary>
public static bool operator <(CircleFraction a, CircleFraction b) => a.Numerator * b.Denominator < b.Numerator * a.Denominator;
/// <summary>Greater-than comparison operator.</summary>
public static bool operator >(CircleFraction a, CircleFraction b) => a.Numerator * b.Denominator > b.Numerator * a.Denominator;
/// <summary>Less-than-or-equal-to comparison operator.</summary>
public static bool operator <=(CircleFraction a, CircleFraction b) => a.Numerator * b.Denominator <= b.Numerator * a.Denominator;
/// <summary>Greater-than-or-equal-to comparison operator.</summary>
public static bool operator >=(CircleFraction a, CircleFraction b) => a.Numerator * b.Denominator >= b.Numerator * a.Denominator;
/// <summary>Equality comparison operator.</summary>
public static bool operator ==(CircleFraction a, CircleFraction b) => a.Numerator * b.Denominator == b.Numerator * a.Denominator;
/// <summary>Inequality comparison operator.</summary>
public static bool operator !=(CircleFraction a, CircleFraction b) => a.Numerator * b.Denominator != b.Numerator * a.Denominator;
/// <summary>
/// Determines whether the current value is strictly between <paramref name="min"/> and <paramref name="max"/>
/// (exclusive).</summary>
public bool IsStrictlyBetween(CircleFraction min, CircleFraction max) => max > min ? (this > min && this < max) : (this > min || this < max);
/// <summary>
/// Determines whether the current value is between <paramref name="min"/> and <paramref name="max"/> (inclusive).</summary>
public bool IsBetweenInclusive(CircleFraction min, CircleFraction max) => max > min ? (this >= min && this <= max) : (this >= min || this <= max);
/// <summary>Addition operator.</summary>
public static double operator +(CircleFraction a, double b) => b + ((double) a.Numerator / a.Denominator);
/// <summary>Addition operator.</summary>
public static double operator +(double b, CircleFraction a) => b + ((double) a.Numerator / a.Denominator);
/// <summary>Subtraction operator.</summary>
public static double operator -(CircleFraction a, double b) => ((double) a.Numerator / a.Denominator) - b;
/// <summary>Subtraction operator.</summary>
public static double operator -(double b, CircleFraction a) => b - ((double) a.Numerator / a.Denominator);
/// <summary>Multiplication operator.</summary>
public static double operator *(CircleFraction a, double b) => b * a.Numerator / a.Denominator;
/// <summary>Multiplication operator.</summary>
public static double operator *(double b, CircleFraction a) => b * a.Numerator / a.Denominator;
/// <summary>Division operator.</summary>
public static double operator /(CircleFraction a, double b) => (double) a.Numerator / a.Denominator / b;
/// <summary>Division operator.</summary>
public static double operator /(double b, CircleFraction a) => b * a.Denominator / a.Numerator;
/// <inheritdoc/>
public int CompareTo(CircleFraction other) => (Numerator * other.Denominator).CompareTo(other.Numerator * Denominator);
/// <inheritdoc/>
public bool Equals(CircleFraction other) => other.Numerator == Numerator && other.Denominator == Denominator;
/// <inheritdoc/>
public override bool Equals(object obj) => obj is CircleFraction other && other.Numerator == Numerator && other.Denominator == Denominator;
/// <inheritdoc/>
public override int GetHashCode() => unchecked(Numerator * 28935701 + Denominator);
/// <inheritdoc/>
public override readonly string ToString() => $"{Numerator}/{Denominator}";
}
}