From 95020e0db04177bcb97b17f00615e260e88d0dc5 Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Thu, 21 Apr 2022 17:43:56 +0100 Subject: [PATCH] Move math-related extensions to child namespace (#7) --- X10D.Tests/src/Core/DoubleTests.cs | 2 + X10D/src/ByteExtensions/SByteExtensions.cs | 2 +- X10D/src/DoubleExtensions/DoubleExtensions.cs | 341 +----------------- X10D/src/Int16Extensions/Int16Extensions.cs | 4 +- X10D/src/Int32Extensions/Int32Extensions.cs | 4 +- X10D/src/Int64Extensions/Int64Extensions.cs | 4 +- X10D/src/Math/DoubleExtensions.cs | 315 ++++++++++++++++ X10D/src/Numerics/DoubleExtensions.cs | 35 ++ .../StringBuilderReader.cs | 6 +- X10D/src/StringExtensions/StringExtensions.cs | 11 +- 10 files changed, 370 insertions(+), 354 deletions(-) create mode 100644 X10D/src/Math/DoubleExtensions.cs create mode 100644 X10D/src/Numerics/DoubleExtensions.cs diff --git a/X10D.Tests/src/Core/DoubleTests.cs b/X10D.Tests/src/Core/DoubleTests.cs index d0bedcf..f8f59a4 100644 --- a/X10D.Tests/src/Core/DoubleTests.cs +++ b/X10D.Tests/src/Core/DoubleTests.cs @@ -1,5 +1,7 @@ using System.Diagnostics; using System.Numerics; +using X10D.Math; +using X10D.Numerics; namespace X10D.Tests.Core; diff --git a/X10D/src/ByteExtensions/SByteExtensions.cs b/X10D/src/ByteExtensions/SByteExtensions.cs index 5190a41..8930448 100644 --- a/X10D/src/ByteExtensions/SByteExtensions.cs +++ b/X10D/src/ByteExtensions/SByteExtensions.cs @@ -78,6 +78,6 @@ public static class SByteExtensions [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static int Sign(this sbyte value) { - return Math.Sign(value); + return System.Math.Sign(value); } } diff --git a/X10D/src/DoubleExtensions/DoubleExtensions.cs b/X10D/src/DoubleExtensions/DoubleExtensions.cs index 6d99042..8f52b54 100644 --- a/X10D/src/DoubleExtensions/DoubleExtensions.cs +++ b/X10D/src/DoubleExtensions/DoubleExtensions.cs @@ -1,177 +1,10 @@ -using System.Diagnostics.Contracts; -using System.Numerics; -using System.Runtime.CompilerServices; - -namespace X10D; +namespace X10D; /// /// Extension methods for . /// public static class DoubleExtensions { - /// - /// Returns the arccosine of the specified value. - /// - /// - /// The value representing a cosine, which must be greater than or equal to -1, but less than or equal to 1. - /// - /// - /// The arccosine of , θ, measured in radians; such that 0 ≤ θ ≤ π. If - /// is equal to , less than -1, or greater than 1, is returned. - /// - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static double Acos(this double value) - { - return Math.Acos(value); - } - - /// - /// Returns the hyperbolic arccosine of the specified value. - /// - /// - /// The value representing a hyperbolic cosine, which must be greater than or equal to 1, but less than or equal to - /// . - /// - /// - /// The hyperbolic arccosine of , θ, measured in radians; such that 0 ≤ θ ≤ ∞. If - /// is less than 1 or equal to , is returned. - /// - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static double Acosh(this double value) - { - return Math.Acosh(value); - } - - /// - /// Returns the arcsine of the specified value. - /// - /// - /// The value representing a sine, which must be greater than or equal to -1, but less than or equal to 1. - /// - /// - /// The arccosine of , θ, measured in radians; such that π/2 ≤ θ ≤ π/2. If - /// is equal to , less than -1, or greater than 1, - /// is returned. - /// - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static double Asin(this double value) - { - return Math.Asin(value); - } - - /// - /// Returns the hyperbolic arcsine of the specified value. - /// - /// - /// The value representing a hyperbolic sine, which must be greater than or equal to 1, but less than or equal to - /// . - /// - /// - /// The hyperbolic arccosine of , measured in radians. If is equal to - /// , is returned. - /// - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static double Asinh(this double value) - { - return Math.Asinh(value); - } - - /// - /// Returns the arctangent of the specified value. - /// - /// - /// The value representing a tangent, which must be greater than or equal to -1, but less than or equal to 1. - /// - /// - /// The arctangent of , θ, measured in radians; such that π/2 ≤ θ ≤ π/2. If - /// is equal to , is returned. - /// - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static double Atan(this double value) - { - return Math.Atan(value); - } - - /// - /// Returns the hyperbolic arctangent of the specified value. - /// - /// - /// The value representing a hyperbolic tangent, which must be greater than or equal to 1, but less than or equal to - /// . - /// - /// - /// The hyperbolic arctangent of , θ, measured in radians; such that -∞ < θ < -1, or 1 < - /// θ < ∞. If is equal to , less than -1, or greater than 1, - /// is returned. - /// - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static double Atanh(this double value) - { - return Math.Atanh(value); - } - - /// - /// Returns the complex square root of this double-precision floating-point number. - /// - /// The number whose square root is to be found. - /// The square root of . - /// - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static Complex ComplexSqrt(this double value) - { - switch (value) - { - case double.PositiveInfinity: - case double.NegativeInfinity: - return Complex.Infinity; - case double.NaN: - return Complex.NaN; - } - - double absoluteSqrt = Math.Abs(value).Sqrt(); - return new Complex(absoluteSqrt, value >= 0 ? 0 : 1); - } - - /// - /// Returns the cosine of the specified angle. - /// - /// The angle, measured in radians. - /// - /// The cosine of . If is equal to , - /// , or , this method returns - /// . - /// - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static double Cos(this double value) - { - return Math.Cos(value); - } - - /// - /// Returns the hyperbolic cosine of the specified angle. - /// - /// The angle, measured in radians. - /// - /// The hyperbolic cosine of . If is equal to - /// or , - /// is returned. If is equal to - /// , is returned. - /// - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static double Cosh(this double value) - { - return Math.Cosh(value); - } - /// /// Converts the current angle in degrees to its equivalent represented in radians. /// @@ -179,7 +12,7 @@ public static class DoubleExtensions /// The result of π * / 180. public static double DegreesToRadians(this double value) { - return value * (Math.PI / 180.0); + return value * (System.Math.PI / 180.0); } /// @@ -202,7 +35,7 @@ public static class DoubleExtensions /// public static bool IsEven(this double value) { - return Math.Abs(value % 2.0) < double.Epsilon; + return System.Math.Abs(value % 2.0) < double.Epsilon; } /// @@ -267,7 +100,7 @@ public static class DoubleExtensions /// The result of π * / 180. public static double RadiansToDegrees(this double value) { - return value * (180.0 / Math.PI); + return value * (180.0 / System.Math.PI); } /// @@ -288,170 +121,6 @@ public static class DoubleExtensions /// rounded to the nearest multiple of . public static double Round(this double value, double nearest) { - return Math.Round(value / nearest) * nearest; - } - - /// - /// Returns an integer that indicates the sign of this double-precision floating-point number. - /// - /// A signed number. - /// - /// A number that indicates the sign of , as shown in the following table. - /// - /// - /// - /// Return value - /// Meaning - /// - /// - /// - /// -1 - /// is less than zero. - /// - /// - /// 0 - /// is equal to zero. - /// - /// - /// 1 - /// is greater than zero. - /// - /// - /// - /// is equal to . - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static int Sign(this double value) - { - return Math.Sign(value); - } - - /// - /// Returns the sine of the specified angle. - /// - /// The angle, in radians. - /// - /// The sine of . If is equal to , - /// , or , this method returns - /// . - /// - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static double Sin(this double value) - { - return Math.Sin(value); - } - - /// - /// Returns the hyperbolic sine of the specified angle. - /// - /// The angle, in radians. - /// - /// The hyperbolic sine of . If is equal to , - /// , or , this method returns - /// . - /// - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static double Sinh(this double value) - { - return Math.Sinh(value); - } - - /// - /// Returns the square root of this double-precision floating-point number. - /// - /// The number whose square root is to be found. - /// - /// One of the values in the following table. - /// - /// - /// - /// Return value - /// Meaning - /// - /// - /// - /// The positive square root of . - /// is greater than or equal to 0. - /// - /// - /// - /// is equal to or is negative. - /// - /// - /// - /// is equal to . - /// - /// - /// - /// - /// For negative input, this method returns . To receive a complex number, see - /// . - /// - /// - /// SLenik https://stackoverflow.com/a/6755197/1467293 - /// CC BY-SA 3.0 - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static double Sqrt(this double value) - { - switch (value) - { - case 0: - return 0; - case < 0 or double.NaN: - return double.NaN; - case double.PositiveInfinity: - return double.PositiveInfinity; - } - - double previous; - double current = Math.Sqrt(value); - do - { - previous = current; - if (previous == 0.0) - { - return 0; - } - - current = (previous + value / previous) / 2; - } while (Math.Abs(previous - current) > double.Epsilon); - - return current; - } - - /// - /// Returns the tangent of the specified angle. - /// - /// The angle, measured in radians. - /// - /// The tangent of . If is equal to , - /// , or , this method returns - /// . - /// - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static double Tan(this double value) - { - return Math.Tan(value); - } - - /// - /// Returns the hyperbolic tangent of the specified angle. - /// - /// The angle, measured in radians. - /// - /// The hyperbolic tangent of . If is equal to - /// , this method returns -1. If is equal to - /// , this method returns 1. If is equal to - /// , this method returns . - /// - [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - public static double Tanh(this double value) - { - return Math.Tanh(value); + return System.Math.Round(value / nearest) * nearest; } } diff --git a/X10D/src/Int16Extensions/Int16Extensions.cs b/X10D/src/Int16Extensions/Int16Extensions.cs index 4abae6d..25313db 100644 --- a/X10D/src/Int16Extensions/Int16Extensions.cs +++ b/X10D/src/Int16Extensions/Int16Extensions.cs @@ -242,7 +242,7 @@ public static class Int16Extensions [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static int Sign(this short value) { - return Math.Sign(value); + return System.Math.Sign(value); } /// @@ -317,7 +317,7 @@ public static class Int16Extensions } else { - short absStep = Math.Abs(step); + short absStep = System.Math.Abs(step); for (short i = start; i >= end; i -= absStep) { yield return i; diff --git a/X10D/src/Int32Extensions/Int32Extensions.cs b/X10D/src/Int32Extensions/Int32Extensions.cs index 2bca722..769ade7 100644 --- a/X10D/src/Int32Extensions/Int32Extensions.cs +++ b/X10D/src/Int32Extensions/Int32Extensions.cs @@ -294,7 +294,7 @@ public static class Int32Extensions [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static int Sign(this int value) { - return Math.Sign(value); + return System.Math.Sign(value); } /// @@ -369,7 +369,7 @@ public static class Int32Extensions } else { - int absStep = Math.Abs(step); + int absStep = System.Math.Abs(step); for (int i = start; i >= end; i -= absStep) { yield return i; diff --git a/X10D/src/Int64Extensions/Int64Extensions.cs b/X10D/src/Int64Extensions/Int64Extensions.cs index 28774ce..7efaf4e 100644 --- a/X10D/src/Int64Extensions/Int64Extensions.cs +++ b/X10D/src/Int64Extensions/Int64Extensions.cs @@ -267,7 +267,7 @@ public static class Int64Extensions [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static int Sign(this long value) { - return Math.Sign(value); + return System.Math.Sign(value); } /// @@ -342,7 +342,7 @@ public static class Int64Extensions } else { - long absStep = Math.Abs(step); + long absStep = System.Math.Abs(step); for (long i = start; i >= end; i -= absStep) { yield return i; diff --git a/X10D/src/Math/DoubleExtensions.cs b/X10D/src/Math/DoubleExtensions.cs new file mode 100644 index 0000000..96fba91 --- /dev/null +++ b/X10D/src/Math/DoubleExtensions.cs @@ -0,0 +1,315 @@ +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; +using X10D.Numerics; + +namespace X10D.Math; + +/// +/// Mathematical extension methods. +/// +public static class DoubleExtensions +{ + /// + /// Returns the arccosine of the specified value. + /// + /// + /// The value representing a cosine, which must be greater than or equal to -1, but less than or equal to 1. + /// + /// + /// The arccosine of , θ, measured in radians; such that 0 ≤ θ ≤ π. If + /// is equal to , less than -1, or greater than 1, is returned. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static double Acos(this double value) + { + return System.Math.Acos(value); + } + + /// + /// Returns the hyperbolic arccosine of the specified value. + /// + /// + /// The value representing a hyperbolic cosine, which must be greater than or equal to 1, but less than or equal to + /// . + /// + /// + /// The hyperbolic arccosine of , θ, measured in radians; such that 0 ≤ θ ≤ ∞. If + /// is less than 1 or equal to , is returned. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static double Acosh(this double value) + { + return System.Math.Acosh(value); + } + + /// + /// Returns the arcsine of the specified value. + /// + /// + /// The value representing a sine, which must be greater than or equal to -1, but less than or equal to 1. + /// + /// + /// The arccosine of , θ, measured in radians; such that π/2 ≤ θ ≤ π/2. If + /// is equal to , less than -1, or greater than 1, + /// is returned. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static double Asin(this double value) + { + return System.Math.Asin(value); + } + + /// + /// Returns the hyperbolic arcsine of the specified value. + /// + /// + /// The value representing a hyperbolic sine, which must be greater than or equal to 1, but less than or equal to + /// . + /// + /// + /// The hyperbolic arccosine of , measured in radians. If is equal to + /// , is returned. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static double Asinh(this double value) + { + return System.Math.Asinh(value); + } + + /// + /// Returns the arctangent of the specified value. + /// + /// + /// The value representing a tangent, which must be greater than or equal to -1, but less than or equal to 1. + /// + /// + /// The arctangent of , θ, measured in radians; such that π/2 ≤ θ ≤ π/2. If + /// is equal to , is returned. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static double Atan(this double value) + { + return System.Math.Atan(value); + } + + /// + /// Returns the hyperbolic arctangent of the specified value. + /// + /// + /// The value representing a hyperbolic tangent, which must be greater than or equal to 1, but less than or equal to + /// . + /// + /// + /// The hyperbolic arctangent of , θ, measured in radians; such that -∞ < θ < -1, or 1 < + /// θ < ∞. If is equal to , less than -1, or greater than 1, + /// is returned. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static double Atanh(this double value) + { + return System.Math.Atanh(value); + } + + /// + /// Returns the cosine of the specified angle. + /// + /// The angle, measured in radians. + /// + /// The cosine of . If is equal to , + /// , or , this method returns + /// . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static double Cos(this double value) + { + return System.Math.Cos(value); + } + + /// + /// Returns the hyperbolic cosine of the specified angle. + /// + /// The angle, measured in radians. + /// + /// The hyperbolic cosine of . If is equal to + /// or , + /// is returned. If is equal to + /// , is returned. + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static double Cosh(this double value) + { + return System.Math.Cosh(value); + } + + /// + /// Returns the sine of the specified angle. + /// + /// The angle, in radians. + /// + /// The sine of . If is equal to , + /// , or , this method returns + /// . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static double Sin(this double value) + { + return System.Math.Sin(value); + } + + /// + /// Returns the hyperbolic sine of the specified angle. + /// + /// The angle, in radians. + /// + /// The hyperbolic sine of . If is equal to , + /// , or , this method returns + /// . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static double Sinh(this double value) + { + return System.Math.Sinh(value); + } + + /// + /// Returns an integer that indicates the sign of this double-precision floating-point number. + /// + /// A signed number. + /// + /// A number that indicates the sign of , as shown in the following table. + /// + /// + /// + /// Return value + /// Meaning + /// + /// + /// + /// -1 + /// is less than zero. + /// + /// + /// 0 + /// is equal to zero. + /// + /// + /// 1 + /// is greater than zero. + /// + /// + /// + /// is equal to . + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static int Sign(this double value) + { + return System.Math.Sign(value); + } + + /// + /// Returns the square root of this double-precision floating-point number. + /// + /// The number whose square root is to be found. + /// + /// One of the values in the following table. + /// + /// + /// + /// Return value + /// Meaning + /// + /// + /// + /// The positive square root of . + /// is greater than or equal to 0. + /// + /// + /// + /// is equal to or is negative. + /// + /// + /// + /// is equal to . + /// + /// + /// + /// + /// For negative input, this method returns . To receive a complex number, see + /// . + /// + /// + /// SLenik https://stackoverflow.com/a/6755197/1467293 + /// CC BY-SA 3.0 + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static double Sqrt(this double value) + { + switch (value) + { + case 0: + return 0; + case < 0 or double.NaN: + return double.NaN; + case double.PositiveInfinity: + return double.PositiveInfinity; + } + + double previous; + double current = System.Math.Sqrt(value); + do + { + previous = current; + if (previous == 0.0) + { + return 0; + } + + current = (previous + value / previous) / 2; + } while (System.Math.Abs(previous - current) > double.Epsilon); + + return current; + } + + /// + /// Returns the tangent of the specified angle. + /// + /// The angle, measured in radians. + /// + /// The tangent of . If is equal to , + /// , or , this method returns + /// . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static double Tan(this double value) + { + return System.Math.Tan(value); + } + + /// + /// Returns the hyperbolic tangent of the specified angle. + /// + /// The angle, measured in radians. + /// + /// The hyperbolic tangent of . If is equal to + /// , this method returns -1. If is equal to + /// , this method returns 1. If is equal to + /// , this method returns . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static double Tanh(this double value) + { + return System.Math.Tanh(value); + } +} diff --git a/X10D/src/Numerics/DoubleExtensions.cs b/X10D/src/Numerics/DoubleExtensions.cs new file mode 100644 index 0000000..f2a1bb6 --- /dev/null +++ b/X10D/src/Numerics/DoubleExtensions.cs @@ -0,0 +1,35 @@ +using System.Diagnostics.Contracts; +using System.Numerics; +using System.Runtime.CompilerServices; +using X10D.Math; + +namespace X10D.Numerics; + +/// +/// Extension methods which accept or return types within . +/// +public static class DoubleExtensions +{ + /// + /// Returns the complex square root of this double-precision floating-point number. + /// + /// The number whose square root is to be found. + /// The square root of . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static Complex ComplexSqrt(this double value) + { + switch (value) + { + case double.PositiveInfinity: + case double.NegativeInfinity: + return Complex.Infinity; + case double.NaN: + return Complex.NaN; + } + + double absoluteSqrt = System.Math.Abs(value).Sqrt(); + return new Complex(absoluteSqrt, value >= 0 ? 0 : 1); + } +} diff --git a/X10D/src/StringBuilderExtensions/StringBuilderReader.cs b/X10D/src/StringBuilderExtensions/StringBuilderReader.cs index e68f353..ddc3eba 100644 --- a/X10D/src/StringBuilderExtensions/StringBuilderReader.cs +++ b/X10D/src/StringBuilderExtensions/StringBuilderReader.cs @@ -80,7 +80,7 @@ public class StringBuilderReader : TextReader return -1; } - int length = Math.Min(_stringBuilder.Length - _index, count); + int length = System.Math.Min(_stringBuilder.Length - _index, count); _stringBuilder.CopyTo(_index, buffer, index, length); _index += length; return length; @@ -89,7 +89,7 @@ public class StringBuilderReader : TextReader /// public override int Read(Span buffer) { - int count = Math.Min(buffer.Length, _stringBuilder.Length - _index); + int count = System.Math.Min(buffer.Length, _stringBuilder.Length - _index); for (var index = 0; index < count; index++) { buffer[index] = _stringBuilder[index + _index]; @@ -138,7 +138,7 @@ public class StringBuilderReader : TextReader return -1; } - int length = Math.Min(count, _stringBuilder.Length - _index); + int length = System.Math.Min(count, _stringBuilder.Length - _index); _stringBuilder.CopyTo(_index, buffer, index, length); _index += length; return length; diff --git a/X10D/src/StringExtensions/StringExtensions.cs b/X10D/src/StringExtensions/StringExtensions.cs index 66fda0b..f8abe5c 100644 --- a/X10D/src/StringExtensions/StringExtensions.cs +++ b/X10D/src/StringExtensions/StringExtensions.cs @@ -326,7 +326,7 @@ public static class StringExtensions { return string.Empty; } - + random ??= Random.Shared; char[] array = source.ToCharArray(); @@ -454,14 +454,9 @@ public static class StringExtensions throw new ArgumentNullException(nameof(value)); } - return SplitInternal(); - - IEnumerable SplitInternal() + for (var i = 0; i < value.Length; i += chunkSize) { - for (var i = 0; i < value.Length; i += chunkSize) - { - yield return value.Substring(i, Math.Min(chunkSize, value.Length - i)); - } + yield return value[i..System.Math.Min(i + chunkSize, value.Length - 1)]; } }