From 516e70709d15f3595286d49150a132e93f277050 Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Sun, 2 Apr 2023 17:40:25 -0400 Subject: [PATCH] made the rational struct immutable ill add a mutable equivalent in 2.4.1 --- Nerd_STF/Helpers/RationalHelper.cs | 6 +- Nerd_STF/Mathematics/Rational.cs | 107 +++++++++-------------------- 2 files changed, 37 insertions(+), 76 deletions(-) diff --git a/Nerd_STF/Helpers/RationalHelper.cs b/Nerd_STF/Helpers/RationalHelper.cs index 89c68d0..645d8a0 100644 --- a/Nerd_STF/Helpers/RationalHelper.cs +++ b/Nerd_STF/Helpers/RationalHelper.cs @@ -28,7 +28,7 @@ internal static class RationalHelper do { - result = new(min.Numerator + max.Numerator, min.Denominator + max.Denominator, false); + result = new(min.numerator + max.numerator, min.denominator + max.denominator, false); resultValue = result.GetValue(); if (remainder == resultValue) break; @@ -40,7 +40,9 @@ internal static class RationalHelper } while (Mathf.Absolute(resultValue - value) > tolerance); - result.Numerator += additional * result.Denominator; + if (additional != 0) + result = new(result.numerator + additional * result.denominator, result.denominator); + return result; } } diff --git a/Nerd_STF/Mathematics/Rational.cs b/Nerd_STF/Mathematics/Rational.cs index d61b86a..a7410c6 100644 --- a/Nerd_STF/Mathematics/Rational.cs +++ b/Nerd_STF/Mathematics/Rational.cs @@ -1,8 +1,8 @@ namespace Nerd_STF.Mathematics; -public record struct Rational : IAbsolute, IAverage, ICeiling, IClamp, +public readonly record struct Rational : IAbsolute, IAverage, ICeiling, IClamp, IComparable, IComparable, IDivide, IEquatable, IEquatable, - IFloor, IIndexAll, IIndexRangeAll, ILerp, IMathOperators, + IFloor, IIndexGet, IIndexRangeGet, ILerp, IMathOperators, IMax, IMedian, IMin, IPresets1d, IProduct, IRound, ISplittable, ISubtract, ISum @@ -10,37 +10,18 @@ public record struct Rational : IAbsolute, IAverage, ICeilin public static Rational One => new(1, 1); public static Rational Zero => new(0, 1); - public int Numerator - { - get => p_num; - set => p_num = value; - } - public int Denominator - { - get => p_den; - set - { - if (Math.Sign(value) == -1) - { - p_num *= -1; - p_den = -value; - } - else p_den = value; - } - } + public readonly int numerator; + public readonly int denominator; - private int p_num; - private int p_den; - - public Rational Reciprocal => new(p_den, p_num); + public Rational Reciprocal => new(denominator, numerator); public Rational Simplified { get { - int[] denFactors = Mathf.PrimeFactors(p_den); + int[] denFactors = Mathf.PrimeFactors(denominator); - int newNum = p_num, - newDen = p_den; + int newNum = numerator, + newDen = denominator; foreach (int factor in denFactors) { @@ -57,8 +38,8 @@ public record struct Rational : IAbsolute, IAverage, ICeilin public Rational() : this(0, 1) { } public Rational(int numerator, int denominator, bool simplified = true) { - Numerator = numerator; - Denominator = denominator; + this.numerator = numerator * Math.Sign(denominator); + this.denominator = Mathf.Absolute(denominator); if (simplified) this = Simplified; } public Rational(Fill fill, bool simplified = true) : this(fill(0), fill(1), simplified) { } @@ -67,30 +48,14 @@ public record struct Rational : IAbsolute, IAverage, ICeilin { get => index switch { - 0 => p_num, - 1 => p_den, + 0 => numerator, + 1 => denominator, _ => throw new IndexOutOfRangeException(nameof(index)) }; - set - { - switch (index) - { - case 0: - p_num = value; - break; - - case 1: - p_den = value; - break; - - default: throw new IndexOutOfRangeException(nameof(index)); - } - } } public int this[Index index] { get => this[index.IsFromEnd ? 2 - index.Value : index.Value]; - set => this[index.IsFromEnd ? 2 - index.Value : index.Value] = value; } public int[] this[Range range] { @@ -102,12 +67,6 @@ public record struct Rational : IAbsolute, IAverage, ICeilin for (int i = start; i < end; i++) res.Add(this[i]); return res.ToArray(); } - set - { - int start = range.Start.IsFromEnd ? 2 - range.Start.Value : range.Start.Value; - int end = range.End.IsFromEnd ? 2 - range.End.Value : range.End.Value; - for (int i = start; i < end; i++) this[i] = value[i]; - } } public static Rational FromFloat(float value, float tolerance = 1e-5f, @@ -120,20 +79,20 @@ public record struct Rational : IAbsolute, IAverage, ICeilin }; public static Rational Absolute(Rational value) => - new(Mathf.Absolute(value.p_num), value.p_den); + new(Mathf.Absolute(value.numerator), value.denominator); public static Rational Average(params Rational[] vals) => Sum(vals) / (float)vals.Length; public static int Ceiling(Rational r) { - int mod = r.p_num % r.p_den; + int mod = r.numerator % r.denominator; - if (mod == 0) return r.p_num / r.p_den; - return r.p_num + (r.p_den - mod); + if (mod == 0) return r.numerator / r.denominator; + return r.numerator + (r.denominator - mod); } public static Rational Clamp(Rational val, Rational min, Rational max) => FromFloat(Mathf.Clamp(val.GetValue(), min.GetValue(), max.GetValue())); public static Rational Divide(Rational val, params Rational[] vals) => val / Product(vals); - public static int Floor(Rational val) => val.p_num / val.p_den; + public static int Floor(Rational val) => val.numerator / val.denominator; public static Rational Lerp(Rational a, Rational b, float t, bool clamp = true) => FromFloat(Mathf.Lerp(a.GetValue(), b.GetValue(), t, clamp)); public static Rational Product(params Rational[] vals) @@ -142,7 +101,7 @@ public record struct Rational : IAbsolute, IAverage, ICeilin foreach (Rational r in vals) res *= r; return res; } - public static int Round(Rational r) => (int)Mathf.Round(r.p_num, r.p_den) / r.p_den; + public static int Round(Rational r) => (int)Mathf.Round(r.numerator, r.denominator) / r.denominator; public static Rational Subtract(Rational val, params Rational[] vals) => val - Sum(vals); public static Rational Sum(params Rational[] vals) @@ -157,13 +116,13 @@ public record struct Rational : IAbsolute, IAverage, ICeilin int[] nums = new int[vals.Length], dens = new int[vals.Length]; for (int i = 0; i < vals.Length; i++) { - nums[i] = vals[i].p_num; - dens[i] = vals[i].p_den; + nums[i] = vals[i].numerator; + dens[i] = vals[i].denominator; } return (nums, dens); } - public float GetValue() => p_num / (float)p_den; + public float GetValue() => numerator / (float)denominator; public int CompareTo(Rational other) => GetValue().CompareTo(other.GetValue()); public int CompareTo(float other) => GetValue().CompareTo(other); @@ -171,42 +130,42 @@ public record struct Rational : IAbsolute, IAverage, ICeilin { Rational thisSim = Simplified, otherSim = other.Simplified; - return thisSim.p_num == otherSim.p_num && - thisSim.p_den == otherSim.p_den; + return thisSim.numerator == otherSim.numerator && + thisSim.denominator == otherSim.denominator; } public bool Equals(float other) => GetValue() == other; public override int GetHashCode() => base.GetHashCode(); private bool PrintMembers(StringBuilder builder) { - builder.Append(p_num); + builder.Append(numerator); builder.Append(" / "); - builder.Append(p_den); + builder.Append(denominator); return true; } public static Rational operator +(Rational a, Rational b) { - int sharedDen = a.p_den * b.p_den, - newNumA = a.p_num * b.p_den, - newNumB = b.p_num * a.p_den; + int sharedDen = a.denominator * b.denominator, + newNumA = a.numerator * b.denominator, + newNumB = b.numerator * a.denominator; return new Rational(newNumA + newNumB, sharedDen).Simplified; } public static Rational operator +(Rational a, float b) => a + FromFloat(b); public static Rational operator +(float a, Rational b) => FromFloat(a) + b; - public static Rational operator -(Rational r) => new(-r.p_num, r.p_den); + public static Rational operator -(Rational r) => new(-r.numerator, r.denominator); public static Rational operator -(Rational a, Rational b) { - int sharedDen = a.p_den * b.p_den, - newNumA = a.p_num * b.p_den, - newNumB = b.p_num * a.p_den; + int sharedDen = a.denominator * b.denominator, + newNumA = a.numerator * b.denominator, + newNumB = b.numerator * a.denominator; return new Rational(newNumA - newNumB, sharedDen).Simplified; } public static Rational operator -(Rational a, float b) => a - FromFloat(b); public static Rational operator -(float a, Rational b) => FromFloat(a) - b; public static Rational operator *(Rational a, Rational b) => - new Rational(a.p_num * b.p_num, a.p_den * b.p_den); + new Rational(a.numerator * b.numerator, a.denominator * b.denominator).Simplified; public static Rational operator *(Rational a, float b) => a * FromFloat(b); public static Rational operator *(float a, Rational b) => FromFloat(a) * b; public static Rational operator /(Rational a, Rational b) => a * b.Reciprocal;