mirror of
https://github.com/oliverbooth/X10D
synced 2024-11-22 09:28:48 +00:00
Merge branch 'refactor/drop-net6.0' into release/4.1.0
This commit is contained in:
commit
15ade9b3f1
4
.github/workflows/dotnet.yml
vendored
4
.github/workflows/dotnet.yml
vendored
@ -23,7 +23,6 @@ jobs:
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: |
|
||||
6.0.x
|
||||
8.0.x
|
||||
|
||||
- name: Add NuGet source
|
||||
@ -35,9 +34,6 @@ jobs:
|
||||
- name: Build
|
||||
run: dotnet build --no-restore --configuration Release
|
||||
|
||||
- name: Test .NET 6
|
||||
run: dotnet test --no-build --verbosity normal --configuration Release --framework net6.0 --collect:"XPlat Code Coverage" --results-directory test-results/net6.0
|
||||
|
||||
- name: Test .NET 8
|
||||
run: dotnet test --no-build --verbosity normal --configuration Release --framework net8.0 --collect:"XPlat Code Coverage" --results-directory test-results/net8.0
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0;net6.0</TargetFrameworks>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0;net6.0</TargetFrameworks>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
<CoverletOutputFormat>xml,cobertura</CoverletOutputFormat>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0;net6.0</TargetFrameworks>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,4 +1,3 @@
|
||||
#if NET7_0_OR_GREATER
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Numerics;
|
||||
@ -95,4 +94,3 @@ public static class BinaryIntegerExtensions
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1,7 +1,3 @@
|
||||
#if !NET7_0_OR_GREATER
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
#endif
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
@ -16,46 +12,6 @@ public static class ByteExtensions
|
||||
{
|
||||
private const int Size = sizeof(byte) * 8;
|
||||
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Unpacks this 8-bit unsigned integer into a boolean list, treating it as a bit field.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to unpack.</param>
|
||||
/// <returns>An array of <see cref="bool" /> with length 8.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool[] Unpack(this byte value)
|
||||
{
|
||||
var buffer = new bool[Size];
|
||||
value.Unpack(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks this 8-bit unsigned integer into a boolean list, treating it as a bit field.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to unpack.</param>
|
||||
/// <param name="destination">When this method returns, contains the unpacked booleans from <paramref name="value" />.</param>
|
||||
/// <exception cref="ArgumentException"><paramref name="destination" /> is not large enough to contain the result.</exception>
|
||||
[ExcludeFromCodeCoverage]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static void Unpack(this byte value, Span<bool> destination)
|
||||
{
|
||||
if (destination.Length < Size)
|
||||
{
|
||||
throw new ArgumentException(ExceptionMessages.DestinationSpanLengthTooShort, nameof(destination));
|
||||
}
|
||||
|
||||
if (Sse3.IsSupported)
|
||||
{
|
||||
UnpackInternal_Ssse3(value, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
UnpackInternal_Fallback(value, destination);
|
||||
}
|
||||
#endif
|
||||
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
internal static void UnpackInternal_Fallback(this byte value, Span<bool> destination)
|
||||
{
|
||||
|
@ -1,7 +1,3 @@
|
||||
#if !NET7_0_OR_GREATER
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
#endif
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
@ -16,46 +12,6 @@ public static class Int16Extensions
|
||||
{
|
||||
private const int Size = sizeof(short) * 8;
|
||||
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Unpacks this 16-bit signed integer into a boolean list, treating it as a bit field.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to unpack.</param>
|
||||
/// <returns>An array of <see cref="bool" /> with length 16.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool[] Unpack(this short value)
|
||||
{
|
||||
var ret = new bool[Size];
|
||||
value.Unpack(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks this 16-bit signed integer into a boolean list, treating it as a bit field.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to unpack.</param>
|
||||
/// <param name="destination">When this method returns, contains the unpacked booleans from <paramref name="value" />.</param>
|
||||
/// <exception cref="ArgumentException"><paramref name="destination" /> is not large enough to contain the result.</exception>
|
||||
[ExcludeFromCodeCoverage]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static void Unpack(this short value, Span<bool> destination)
|
||||
{
|
||||
if (destination.Length < Size)
|
||||
{
|
||||
throw new ArgumentException(ExceptionMessages.DestinationSpanLengthTooShort, nameof(destination));
|
||||
}
|
||||
|
||||
if (Sse3.IsSupported)
|
||||
{
|
||||
UnpackInternal_Ssse3(value, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
UnpackInternal_Fallback(value, destination);
|
||||
}
|
||||
#endif
|
||||
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
internal static void UnpackInternal_Fallback(this short value, Span<bool> destination)
|
||||
{
|
||||
|
@ -1,7 +1,3 @@
|
||||
#if !NET7_0_OR_GREATER
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
#endif
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
@ -16,52 +12,6 @@ public static class Int32Extensions
|
||||
{
|
||||
private const int Size = sizeof(int) * 8;
|
||||
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Unpacks this 32-bit signed integer into a boolean list, treating it as a bit field.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to unpack.</param>
|
||||
/// <returns>An array of <see cref="bool" /> with length 32.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool[] Unpack(this int value)
|
||||
{
|
||||
var ret = new bool[Size];
|
||||
value.Unpack(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks this 32-bit signed integer into a boolean list, treating it as a bit field.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to unpack.</param>
|
||||
/// <param name="destination">When this method returns, contains the unpacked booleans from <paramref name="value" />.</param>
|
||||
/// <exception cref="ArgumentException"><paramref name="destination" /> is not large enough to contain the result.</exception>
|
||||
[ExcludeFromCodeCoverage]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static void Unpack(this int value, Span<bool> destination)
|
||||
{
|
||||
if (destination.Length < Size)
|
||||
{
|
||||
throw new ArgumentException(ExceptionMessages.DestinationSpanLengthTooShort, nameof(destination));
|
||||
}
|
||||
|
||||
if (Avx2.IsSupported)
|
||||
{
|
||||
UnpackInternal_Avx2(value, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Sse3.IsSupported)
|
||||
{
|
||||
UnpackInternal_Ssse3(value, destination);
|
||||
return;
|
||||
}
|
||||
|
||||
UnpackInternal_Fallback(value, destination);
|
||||
}
|
||||
#endif
|
||||
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
internal static void UnpackInternal_Fallback(this int value, Span<bool> destination)
|
||||
{
|
||||
|
@ -1,45 +0,0 @@
|
||||
#if !NET7_0_OR_GREATER
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
namespace X10D.Collections;
|
||||
|
||||
/// <summary>
|
||||
/// Collection-related extension methods for <see cref="long" />.
|
||||
/// </summary>
|
||||
public static class Int64Extensions
|
||||
{
|
||||
private const int Size = sizeof(long) * 8;
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks this 64-bit signed integer into a boolean list, treating it as a bit field.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to unpack.</param>
|
||||
/// <returns>An array of <see cref="bool" /> with length 64.</returns>
|
||||
[Pure]
|
||||
public static bool[] Unpack(this long value)
|
||||
{
|
||||
var ret = new bool[Size];
|
||||
value.Unpack(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks this 64-bit signed integer into a boolean list, treating it as a bit field.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to unpack.</param>
|
||||
/// <param name="destination">When this method returns, contains the unpacked booleans from <paramref name="value" />.</param>
|
||||
/// <exception cref="ArgumentException"><paramref name="destination" /> is not large enough to contain the result.</exception>
|
||||
public static void Unpack(this long value, Span<bool> destination)
|
||||
{
|
||||
if (destination.Length < Size)
|
||||
{
|
||||
throw new ArgumentException(ExceptionMessages.DestinationSpanLengthTooShort, nameof(destination));
|
||||
}
|
||||
|
||||
for (var index = 0; index < Size; index++)
|
||||
{
|
||||
destination[index] = (value & (1L << index)) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -37,12 +37,7 @@ public static class IntrinsicExtensions
|
||||
for (var i = 0; i < Vector64<byte>.Count; i++)
|
||||
{
|
||||
ref byte writeElement = ref Unsafe.Add(ref Unsafe.As<Vector64<byte>, byte>(ref output), i);
|
||||
#if NET7_0_OR_GREATER
|
||||
writeElement = vector[i] == 0 ? (byte)0 : (byte)1;
|
||||
#else
|
||||
byte element = Unsafe.Add(ref Unsafe.As<Vector64<byte>, byte>(ref vector), i);
|
||||
writeElement = element == 0 ? (byte)0 : (byte)1;
|
||||
#endif
|
||||
}
|
||||
|
||||
return output;
|
||||
|
@ -1,3 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.CompilerServices;
|
||||
@ -6,10 +7,6 @@ using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
using X10D.CompilerServices;
|
||||
|
||||
#if NET7_0_OR_GREATER
|
||||
using System.Diagnostics;
|
||||
#endif
|
||||
|
||||
namespace X10D.Core;
|
||||
|
||||
/// <summary>
|
||||
@ -93,11 +90,7 @@ public static class SpanExtensions
|
||||
|
||||
// dotcover disable
|
||||
default:
|
||||
#if NET7_0_OR_GREATER
|
||||
throw new UnreachableException(string.Format(ExceptionMessages.EnumSizeIsUnexpected, Unsafe.SizeOf<T>()));
|
||||
#else
|
||||
throw new ArgumentException(string.Format(ExceptionMessages.EnumSizeIsUnexpected, Unsafe.SizeOf<T>()));
|
||||
#endif
|
||||
// dotcover enable
|
||||
}
|
||||
}
|
||||
|
@ -10,41 +10,6 @@ namespace X10D.Math;
|
||||
/// </summary>
|
||||
public static class BigIntegerExtensions
|
||||
{
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Returns the number of digits in the current integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digit count to compute.</param>
|
||||
/// <returns>The number of digits in <paramref name="value" />.</returns>
|
||||
public static int CountDigits(this BigInteger value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return (int)(1 + BigInteger.Log10(BigInteger.Abs(value)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the digital root of this 8-bit integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digital root to compute.</param>
|
||||
/// <returns>The digital root of <paramref name="value" />.</returns>
|
||||
/// <remarks>The digital root is defined as the recursive sum of digits until that result is a single digit.</remarks>
|
||||
/// <remarks>
|
||||
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
|
||||
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
|
||||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static int DigitalRoot(this BigInteger value)
|
||||
{
|
||||
BigInteger root = BigInteger.Abs(value).Mod(9);
|
||||
return (int)(root == 0 ? 9 : root);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns the factorial of the current 64-bit signed integer.
|
||||
/// </summary>
|
||||
@ -172,30 +137,6 @@ public static class BigIntegerExtensions
|
||||
return value * other / value.GreatestCommonFactor(other);
|
||||
}
|
||||
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Performs a modulo operation which supports a negative dividend.
|
||||
/// </summary>
|
||||
/// <param name="dividend">The dividend.</param>
|
||||
/// <param name="divisor">The divisor.</param>
|
||||
/// <returns>The result of <c>dividend mod divisor</c>.</returns>
|
||||
/// <remarks>
|
||||
/// The <c>%</c> operator (commonly called the modulo operator) in C# is not defined to be modulo, but is instead
|
||||
/// remainder. This quirk inherently makes it difficult to use modulo in a negative context, as <c>x % y</c> where x is
|
||||
/// negative will return a negative value, akin to <c>-(x % y)</c>, even if precedence is forced. This method provides a
|
||||
/// modulo operation which supports negative dividends.
|
||||
/// </remarks>
|
||||
/// <author>ShreevatsaR, https://stackoverflow.com/a/1082938/1467293</author>
|
||||
/// <license>CC-BY-SA 2.5</license>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static BigInteger Mod(this BigInteger dividend, BigInteger divisor)
|
||||
{
|
||||
BigInteger r = dividend % divisor;
|
||||
return r < 0 ? r + divisor : r;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns the multiplicative persistence of a specified value.
|
||||
/// </summary>
|
||||
|
@ -1,4 +1,3 @@
|
||||
#if NET7_0_OR_GREATER
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
@ -98,4 +97,3 @@ public static class BinaryIntegerExtensions
|
||||
return value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -9,107 +9,6 @@ namespace X10D.Math;
|
||||
/// </summary>
|
||||
public static class ByteExtensions
|
||||
{
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Returns the number of digits in the current 8-bit unsigned integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digit count to compute.</param>
|
||||
/// <returns>The number of digits in <paramref name="value" />.</returns>
|
||||
public static int CountDigits(this byte value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ((ulong)value).CountDigits();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the digital root of this 8-bit integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digital root to compute.</param>
|
||||
/// <returns>The digital root of <paramref name="value" />.</returns>
|
||||
/// <remarks>The digital root is defined as the recursive sum of digits until that result is a single digit.</remarks>
|
||||
/// <remarks>
|
||||
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
|
||||
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
|
||||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static byte DigitalRoot(this byte value)
|
||||
{
|
||||
int root = value % 9;
|
||||
return (byte)(root == 0 ? 9 : root);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the factorial of the current 8-bit unsigned integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose factorial to compute.</param>
|
||||
/// <returns>The factorial of <paramref name="value" />.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static long Factorial(this byte value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
var result = 1L;
|
||||
for (byte i = 1; i <= value; i++)
|
||||
{
|
||||
result *= i;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the greatest common factor between the current 8-bit unsigned integer, and another 8-bit unsigned integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The first value.</param>
|
||||
/// <param name="other">The second value.</param>
|
||||
/// <returns>The greatest common factor between <paramref name="value" /> and <paramref name="other" />.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static byte GreatestCommonFactor(this byte value, byte other)
|
||||
{
|
||||
return (byte)((long)value).GreatestCommonFactor(other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsEven(this byte value)
|
||||
{
|
||||
return (value & 1) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is not evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is not evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsOdd(this byte value)
|
||||
{
|
||||
return !value.IsEven();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is a prime number.
|
||||
/// </summary>
|
||||
|
@ -9,112 +9,6 @@ namespace X10D.Math;
|
||||
/// </summary>
|
||||
public static class Int16Extensions
|
||||
{
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Returns the number of digits in the current 16-bit signed integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digit count to compute.</param>
|
||||
/// <returns>The number of digits in <paramref name="value" />.</returns>
|
||||
public static int CountDigits(this short value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ((long)value).CountDigits();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the digital root of this 16-bit integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digital root to compute.</param>
|
||||
/// <returns>The digital root of <paramref name="value" />.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
|
||||
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
|
||||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static short DigitalRoot(this short value)
|
||||
{
|
||||
short root = System.Math.Abs(value).Mod(9);
|
||||
return root < 1 ? (short)(9 - root) : root;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the factorial of the current 16-bit signed integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose factorial to compute.</param>
|
||||
/// <returns>The factorial of <paramref name="value" />.</returns>
|
||||
/// <exception cref="ArithmeticException"><paramref name="value" /> is less than 0.</exception>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static long Factorial(this short value)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw new ArithmeticException(nameof(value));
|
||||
}
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
var result = 1L;
|
||||
for (short i = 1; i <= value; i++)
|
||||
{
|
||||
result *= i;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the greatest common factor between the current 16-bit signed integer, and another 16-bit signed integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The first value.</param>
|
||||
/// <param name="other">The second value.</param>
|
||||
/// <returns>The greatest common factor between <paramref name="value" /> and <paramref name="other" />.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static short GreatestCommonFactor(this short value, short other)
|
||||
{
|
||||
return (short)((long)value).GreatestCommonFactor(other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsEven(this short value)
|
||||
{
|
||||
return (value & 1) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is not evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is not evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsOdd(this short value)
|
||||
{
|
||||
return !value.IsEven();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is a prime number.
|
||||
/// </summary>
|
||||
@ -142,30 +36,6 @@ public static class Int16Extensions
|
||||
return (short)((long)value).LowestCommonMultiple(other);
|
||||
}
|
||||
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Performs a modulo operation which supports a negative dividend.
|
||||
/// </summary>
|
||||
/// <param name="dividend">The dividend.</param>
|
||||
/// <param name="divisor">The divisor.</param>
|
||||
/// <returns>The result of <c>dividend mod divisor</c>.</returns>
|
||||
/// <remarks>
|
||||
/// The <c>%</c> operator (commonly called the modulo operator) in C# is not defined to be modulo, but is instead
|
||||
/// remainder. This quirk inherently makes it difficult to use modulo in a negative context, as <c>x % y</c> where x is
|
||||
/// negative will return a negative value, akin to <c>-(x % y)</c>, even if precedence is forced. This method provides a
|
||||
/// modulo operation which supports negative dividends.
|
||||
/// </remarks>
|
||||
/// <author>ShreevatsaR, https://stackoverflow.com/a/1082938/1467293</author>
|
||||
/// <license>CC-BY-SA 2.5</license>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static short Mod(this short dividend, short divisor)
|
||||
{
|
||||
int r = dividend % divisor;
|
||||
return (short)(r < 0 ? r + divisor : r);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns the multiplicative persistence of a specified value.
|
||||
/// </summary>
|
||||
|
@ -9,112 +9,6 @@ namespace X10D.Math;
|
||||
/// </summary>
|
||||
public static class Int32Extensions
|
||||
{
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Returns the number of digits in the current 32-bit signed integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digit count to compute.</param>
|
||||
/// <returns>The number of digits in <paramref name="value" />.</returns>
|
||||
public static int CountDigits(this int value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ((long)value).CountDigits();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the digital root of this 32-bit integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digital root to compute.</param>
|
||||
/// <returns>The digital root of <paramref name="value" />.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
|
||||
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
|
||||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static int DigitalRoot(this int value)
|
||||
{
|
||||
int root = System.Math.Abs(value).Mod(9);
|
||||
return root < 1 ? 9 - root : root;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the factorial of the current 32-bit signed integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose factorial to compute.</param>
|
||||
/// <returns>The factorial of <paramref name="value" />.</returns>
|
||||
/// <exception cref="ArithmeticException"><paramref name="value" /> is less than 0.</exception>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static long Factorial(this int value)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw new ArithmeticException(nameof(value));
|
||||
}
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
var result = 1L;
|
||||
for (var i = 1; i <= value; i++)
|
||||
{
|
||||
result *= i;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the greatest common factor between the current 32-bit signed integer, and another 32-bit signed integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The first value.</param>
|
||||
/// <param name="other">The second value.</param>
|
||||
/// <returns>The greatest common factor between <paramref name="value" /> and <paramref name="other" />.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static int GreatestCommonFactor(this int value, int other)
|
||||
{
|
||||
return (int)((long)value).GreatestCommonFactor(other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsEven(this int value)
|
||||
{
|
||||
return (value & 1) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is not evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is not evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsOdd(this int value)
|
||||
{
|
||||
return !value.IsEven();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is a prime number.
|
||||
/// </summary>
|
||||
@ -142,30 +36,6 @@ public static class Int32Extensions
|
||||
return (int)((long)value).LowestCommonMultiple(other);
|
||||
}
|
||||
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Performs a modulo operation which supports a negative dividend.
|
||||
/// </summary>
|
||||
/// <param name="dividend">The dividend.</param>
|
||||
/// <param name="divisor">The divisor.</param>
|
||||
/// <returns>The result of <c>dividend mod divisor</c>.</returns>
|
||||
/// <remarks>
|
||||
/// The <c>%</c> operator (commonly called the modulo operator) in C# is not defined to be modulo, but is instead
|
||||
/// remainder. This quirk inherently makes it difficult to use modulo in a negative context, as <c>x % y</c> where x is
|
||||
/// negative will return a negative value, akin to <c>-(x % y)</c>, even if precedence is forced. This method provides a
|
||||
/// modulo operation which supports negative dividends.
|
||||
/// </remarks>
|
||||
/// <author>ShreevatsaR, https://stackoverflow.com/a/1082938/1467293</author>
|
||||
/// <license>CC-BY-SA 2.5</license>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static int Mod(this int dividend, int divisor)
|
||||
{
|
||||
int r = dividend % divisor;
|
||||
return r < 0 ? r + divisor : r;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns the multiplicative persistence of a specified value.
|
||||
/// </summary>
|
||||
|
@ -9,117 +9,6 @@ namespace X10D.Math;
|
||||
/// </summary>
|
||||
public static class Int64Extensions
|
||||
{
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Returns the number of digits in the current 64-bit signed integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digit count to compute.</param>
|
||||
/// <returns>The number of digits in <paramref name="value" />.</returns>
|
||||
public static int CountDigits(this long value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1 + (int)System.Math.Floor(System.Math.Log10(System.Math.Abs(value)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the digital root of this 64-bit integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digital root to compute.</param>
|
||||
/// <returns>The digital root of <paramref name="value" />.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
|
||||
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
|
||||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static long DigitalRoot(this long value)
|
||||
{
|
||||
long root = System.Math.Abs(value).Mod(9L);
|
||||
return root < 1L ? 9L - root : root;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the factorial of the current 64-bit signed integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose factorial to compute.</param>
|
||||
/// <returns>The factorial of <paramref name="value" />.</returns>
|
||||
/// <exception cref="ArithmeticException"><paramref name="value" /> is less than 0.</exception>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static long Factorial(this long value)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw new ArithmeticException(nameof(value));
|
||||
}
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
var result = 1L;
|
||||
for (var i = 1L; i <= value; i++)
|
||||
{
|
||||
result *= i;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the greatest common factor between the current 64-bit signed integer, and another 64-bit unsigned integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The first value.</param>
|
||||
/// <param name="other">The second value.</param>
|
||||
/// <returns>The greatest common factor between <paramref name="value" /> and <paramref name="other" />.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static long GreatestCommonFactor(this long value, long other)
|
||||
{
|
||||
while (other != 0)
|
||||
{
|
||||
(value, other) = (other, value % other);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsEven(this long value)
|
||||
{
|
||||
return (value & 1) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is not evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is not evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsOdd(this long value)
|
||||
{
|
||||
return !value.IsEven();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is a prime number.
|
||||
/// </summary>
|
||||
@ -181,30 +70,6 @@ public static class Int64Extensions
|
||||
return value * other / value.GreatestCommonFactor(other);
|
||||
}
|
||||
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Performs a modulo operation which supports a negative dividend.
|
||||
/// </summary>
|
||||
/// <param name="dividend">The dividend.</param>
|
||||
/// <param name="divisor">The divisor.</param>
|
||||
/// <returns>The result of <c>dividend mod divisor</c>.</returns>
|
||||
/// <remarks>
|
||||
/// The <c>%</c> operator (commonly called the modulo operator) in C# is not defined to be modulo, but is instead
|
||||
/// remainder. This quirk inherently makes it difficult to use modulo in a negative context, as <c>x % y</c> where x is
|
||||
/// negative will return a negative value, akin to <c>-(x % y)</c>, even if precedence is forced. This method provides a
|
||||
/// modulo operation which supports negative dividends.
|
||||
/// </remarks>
|
||||
/// <author>ShreevatsaR, https://stackoverflow.com/a/1082938/1467293</author>
|
||||
/// <license>CC-BY-SA 2.5</license>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static long Mod(this long dividend, long divisor)
|
||||
{
|
||||
long r = dividend % divisor;
|
||||
return r < 0 ? r + divisor : r;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns the multiplicative persistence of a specified value.
|
||||
/// </summary>
|
||||
|
@ -127,158 +127,6 @@ public static class MathUtility
|
||||
return (alpha - start) / (end - start);
|
||||
}
|
||||
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Applies a simple bias function to value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to which the bias function will be applied.</param>
|
||||
/// <param name="bias">The bias value. Valid values range from 0-1.</param>
|
||||
/// <returns>The biased result.</returns>
|
||||
/// <remarks>
|
||||
/// If <paramref name="bias" /> is less than 0.5, <paramref name="value" /> will be shifted downward; otherwise, upward.
|
||||
/// </remarks>
|
||||
public static float Bias(float value, float bias)
|
||||
{
|
||||
return value / ((1.0f / bias - 2.0f) * (1.0f - value) + 1.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a simple bias function to value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to which the bias function will be applied.</param>
|
||||
/// <param name="bias">The bias value. Valid values range from 0-1.</param>
|
||||
/// <returns>The biased result.</returns>
|
||||
/// <remarks>
|
||||
/// If <paramref name="bias" /> is less than 0.5, <paramref name="value" /> will be shifted downward; otherwise, upward.
|
||||
/// </remarks>
|
||||
public static double Bias(double value, double bias)
|
||||
{
|
||||
return value / ((1.0 / bias - 2.0) * (1.0 - value) + 1.0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Linearly interpolates from one value to a target using a specified alpha.
|
||||
/// </summary>
|
||||
/// <param name="value">The interpolation source.</param>
|
||||
/// <param name="target">The interpolation target.</param>
|
||||
/// <param name="alpha">The interpolation alpha.</param>
|
||||
/// <returns>
|
||||
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static float Lerp(float value, float target, float alpha)
|
||||
{
|
||||
// rookie mistake: a + t * (b - a)
|
||||
// "precise" method: (1 - t) * a + t * b
|
||||
return ((1.0f - alpha) * value) + (alpha * target);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Linearly interpolates from one value to a target using a specified alpha.
|
||||
/// </summary>
|
||||
/// <param name="value">The interpolation source.</param>
|
||||
/// <param name="target">The interpolation target.</param>
|
||||
/// <param name="alpha">The interpolation alpha.</param>
|
||||
/// <returns>
|
||||
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static double Lerp(double value, double target, double alpha)
|
||||
{
|
||||
// rookie mistake: a + t * (b - a)
|
||||
// "precise" method: (1 - t) * a + t * b
|
||||
return ((1.0 - alpha) * value) + (alpha * target);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs smooth Hermite interpolation from one value to a target using a specified alpha.
|
||||
/// </summary>
|
||||
/// <param name="value">The interpolation source.</param>
|
||||
/// <param name="target">The interpolation target.</param>
|
||||
/// <param name="alpha">The interpolation alpha.</param>
|
||||
/// <returns>The interpolation result.</returns>
|
||||
public static float SmoothStep(float value, float target, float alpha)
|
||||
{
|
||||
alpha = System.Math.Clamp(alpha, 0.0f, 1.0f);
|
||||
alpha = -2.0f * alpha * alpha * alpha + 3.0f * alpha * alpha;
|
||||
return target * alpha + value * (1.0f - alpha);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs smooth Hermite interpolation from one value to a target using a specified alpha.
|
||||
/// </summary>
|
||||
/// <param name="value">The interpolation source.</param>
|
||||
/// <param name="target">The interpolation target.</param>
|
||||
/// <param name="alpha">The interpolation alpha.</param>
|
||||
/// <returns>The interpolation result.</returns>
|
||||
public static double SmoothStep(double value, double target, double alpha)
|
||||
{
|
||||
alpha = System.Math.Clamp(alpha, 0.0, 1.0);
|
||||
alpha = -2.0 * alpha * alpha * alpha + 3.0 * alpha * alpha;
|
||||
return target * alpha + value * (1.0 - alpha);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a value from being a percentage of one range, to being the same percentage in a new range.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to convert.</param>
|
||||
/// <param name="oldMin">The old minimum value.</param>
|
||||
/// <param name="oldMax">The old maximum value.</param>
|
||||
/// <param name="newMin">The new minimum value.</param>
|
||||
/// <param name="newMax">The new maximum value.</param>
|
||||
/// <returns>The scaled value.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static float ScaleRange(float value, float oldMin, float oldMax, float newMin, float newMax)
|
||||
{
|
||||
float oldRange = oldMax - oldMin;
|
||||
float newRange = newMax - newMin;
|
||||
float alpha = (value - oldMin) / oldRange;
|
||||
return (alpha * newRange) + newMin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a value from being a percentage of one range, to being the same percentage in a new range.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to convert.</param>
|
||||
/// <param name="oldMin">The old minimum value.</param>
|
||||
/// <param name="oldMax">The old maximum value.</param>
|
||||
/// <param name="newMin">The new minimum value.</param>
|
||||
/// <param name="newMax">The new maximum value.</param>
|
||||
/// <returns>The scaled value.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static double ScaleRange(double value, double oldMin, double oldMax, double newMin, double newMax)
|
||||
{
|
||||
double oldRange = oldMax - oldMin;
|
||||
double newRange = newMax - newMin;
|
||||
double alpha = (value - oldMin) / oldRange;
|
||||
return (alpha * newRange) + newMin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the incremental sawtooth wave of a given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to calculate.</param>
|
||||
/// <returns>The sawtooth wave of the given value.</returns>
|
||||
public static float Sawtooth(float value)
|
||||
{
|
||||
return (value - MathF.Floor(value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the incremental sawtooth wave of a given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to calculate.</param>
|
||||
/// <returns>The sawtooth wave of the given value.</returns>
|
||||
public static double Sawtooth(double value)
|
||||
{
|
||||
return (value - System.Math.Floor(value));
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Converts a linear value to a gamma-encoded value using a gamma value of <c>2.2</c>.
|
||||
/// </summary>
|
||||
@ -389,7 +237,6 @@ public static class MathUtility
|
||||
return 1.0f / (1.0f + System.Math.Exp(-value));
|
||||
}
|
||||
|
||||
#if NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Applies a simple bias function to value.
|
||||
/// </summary>
|
||||
@ -474,5 +321,4 @@ public static class MathUtility
|
||||
alpha = -two * alpha * alpha * alpha + three * alpha * alpha;
|
||||
return target * alpha + value * (one - alpha);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
#if NET7_0_OR_GREATER
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
@ -101,4 +100,3 @@ public static class NumberExtensions
|
||||
return TNumber.Sign(value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -10,112 +10,6 @@ namespace X10D.Math;
|
||||
[CLSCompliant(false)]
|
||||
public static class SByteExtensions
|
||||
{
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Returns the number of digits in the current 8-bit signed integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digit count to compute.</param>
|
||||
/// <returns>The number of digits in <paramref name="value" />.</returns>
|
||||
public static int CountDigits(this sbyte value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ((long)value).CountDigits();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the digital root of this 32-bit integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digital root to compute.</param>
|
||||
/// <returns>The digital root of <paramref name="value" />.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
|
||||
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
|
||||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static sbyte DigitalRoot(this sbyte value)
|
||||
{
|
||||
int root = System.Math.Abs(value).Mod(9);
|
||||
return (sbyte)(root < 1 ? 9 - root : root);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the factorial of the current 8-bit signed integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose factorial to compute.</param>
|
||||
/// <returns>The factorial of <paramref name="value" />.</returns>
|
||||
/// <exception cref="ArithmeticException"><paramref name="value" /> is less than 0.</exception>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static long Factorial(this sbyte value)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw new ArithmeticException(nameof(value));
|
||||
}
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
var result = 1L;
|
||||
for (ushort i = 1; i <= value; i++)
|
||||
{
|
||||
result *= i;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the greatest common factor between the current 8-bit signed integer, and another 8-bit signed integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The first value.</param>
|
||||
/// <param name="other">The second value.</param>
|
||||
/// <returns>The greatest common factor between <paramref name="value" /> and <paramref name="other" />.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static sbyte GreatestCommonFactor(this sbyte value, sbyte other)
|
||||
{
|
||||
return (sbyte)((long)value).GreatestCommonFactor(other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsEven(this sbyte value)
|
||||
{
|
||||
return (value & 1) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is not evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is not evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsOdd(this sbyte value)
|
||||
{
|
||||
return !value.IsEven();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is a prime number.
|
||||
/// </summary>
|
||||
@ -143,30 +37,6 @@ public static class SByteExtensions
|
||||
return (sbyte)((long)value).LowestCommonMultiple(other);
|
||||
}
|
||||
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Performs a modulo operation which supports a negative dividend.
|
||||
/// </summary>
|
||||
/// <param name="dividend">The dividend.</param>
|
||||
/// <param name="divisor">The divisor.</param>
|
||||
/// <returns>The result of <c>dividend mod divisor</c>.</returns>
|
||||
/// <remarks>
|
||||
/// The <c>%</c> operator (commonly called the modulo operator) in C# is not defined to be modulo, but is instead
|
||||
/// remainder. This quirk inherently makes it difficult to use modulo in a negative context, as <c>x % y</c> where x is
|
||||
/// negative will return a negative value, akin to <c>-(x % y)</c>, even if precedence is forced. This method provides a
|
||||
/// modulo operation which supports negative dividends.
|
||||
/// </remarks>
|
||||
/// <author>ShreevatsaR, https://stackoverflow.com/a/1082938/1467293</author>
|
||||
/// <license>CC-BY-SA 2.5</license>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static sbyte Mod(this sbyte dividend, sbyte divisor)
|
||||
{
|
||||
int r = dividend % divisor;
|
||||
return (sbyte)(r < 0 ? r + divisor : r);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns the multiplicative persistence of a specified value.
|
||||
/// </summary>
|
||||
|
@ -10,107 +10,6 @@ namespace X10D.Math;
|
||||
[CLSCompliant(false)]
|
||||
public static class UInt16Extensions
|
||||
{
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Returns the number of digits in the current 16-bit signed integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digit count to compute.</param>
|
||||
/// <returns>The number of digits in <paramref name="value" />.</returns>
|
||||
public static int CountDigits(this ushort value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ((ulong)value).CountDigits();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the digital root of the current 16-bit unsigned integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digital root to compute.</param>
|
||||
/// <returns>The digital root of <paramref name="value" />.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
|
||||
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
|
||||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static ushort DigitalRoot(this ushort value)
|
||||
{
|
||||
var root = (ushort)(value % 9);
|
||||
return (ushort)(root == 0 ? 9 : root);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the factorial of the current 16-bit unsigned integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose factorial to compute.</param>
|
||||
/// <returns>The factorial of <paramref name="value" />.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static ulong Factorial(this ushort value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
var result = 1UL;
|
||||
for (ushort i = 1; i <= value; i++)
|
||||
{
|
||||
result *= i;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the greatest common factor between the current 16-bit unsigned integer, and another 16-bit unsigned
|
||||
/// integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The first value.</param>
|
||||
/// <param name="other">The second value.</param>
|
||||
/// <returns>The greatest common factor between <paramref name="value" /> and <paramref name="other" />.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static ushort GreatestCommonFactor(this ushort value, ushort other)
|
||||
{
|
||||
return (ushort)((long)value).GreatestCommonFactor(other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsEven(this ushort value)
|
||||
{
|
||||
return (value & 1) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is not evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is not evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsOdd(this ushort value)
|
||||
{
|
||||
return !value.IsEven();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is a prime number.
|
||||
/// </summary>
|
||||
|
@ -10,107 +10,6 @@ namespace X10D.Math;
|
||||
[CLSCompliant(false)]
|
||||
public static class UInt32Extensions
|
||||
{
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Returns the number of digits in the current 32-bit unsigned integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digit count to compute.</param>
|
||||
/// <returns>The number of digits in <paramref name="value" />.</returns>
|
||||
public static int CountDigits(this uint value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ((ulong)value).CountDigits();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the digital root of the current 32-bit unsigned integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digital root to compute.</param>
|
||||
/// <returns>The digital root of <paramref name="value" />.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
|
||||
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
|
||||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static uint DigitalRoot(this uint value)
|
||||
{
|
||||
uint root = value % 9;
|
||||
return root == 0 ? 9 : root;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the factorial of the current 32-bit unsigned integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose factorial to compute.</param>
|
||||
/// <returns>The factorial of <paramref name="value" />.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static ulong Factorial(this uint value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
var result = 1UL;
|
||||
for (var i = 1U; i <= value; i++)
|
||||
{
|
||||
result *= i;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the greatest common factor between the current 32-bit unsigned integer, and another 32-bit unsigned
|
||||
/// integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The first value.</param>
|
||||
/// <param name="other">The second value.</param>
|
||||
/// <returns>The greatest common factor between <paramref name="value" /> and <paramref name="other" />.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static uint GreatestCommonFactor(this uint value, uint other)
|
||||
{
|
||||
return (uint)((long)value).GreatestCommonFactor(other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsEven(this uint value)
|
||||
{
|
||||
return (value & 1) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is not evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is not evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsOdd(this uint value)
|
||||
{
|
||||
return !value.IsEven();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is a prime number.
|
||||
/// </summary>
|
||||
|
@ -10,112 +10,6 @@ namespace X10D.Math;
|
||||
[CLSCompliant(false)]
|
||||
public static class UInt64Extensions
|
||||
{
|
||||
#if !NET7_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// Returns the number of digits in the current 64-bit unsigned integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digit count to compute.</param>
|
||||
/// <returns>The number of digits in <paramref name="value" />.</returns>
|
||||
public static int CountDigits(this ulong value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1 + (int)System.Math.Floor(System.Math.Log10(System.Math.Abs((double)value)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the digital root of the current 64-bit unsigned integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose digital root to compute.</param>
|
||||
/// <returns>The digital root of <paramref name="value" />.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
|
||||
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
|
||||
/// </remarks>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static ulong DigitalRoot(this ulong value)
|
||||
{
|
||||
ulong root = value % 9;
|
||||
return root == 0 ? 9 : root;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the factorial of the current 64-bit unsigned integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose factorial to compute.</param>
|
||||
/// <returns>The factorial of <paramref name="value" />.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static ulong Factorial(this ulong value)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
var result = 1UL;
|
||||
for (var i = 1UL; i <= value; i++)
|
||||
{
|
||||
result *= i;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the greatest common factor between the current 64-bit unsigned integer, and another 64-bit unsigned
|
||||
/// integer.
|
||||
/// </summary>
|
||||
/// <param name="value">The first value.</param>
|
||||
/// <param name="other">The second value.</param>
|
||||
/// <returns>The greatest common factor between <paramref name="value" /> and <paramref name="other" />.</returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static ulong GreatestCommonFactor(this ulong value, ulong other)
|
||||
{
|
||||
while (other != 0)
|
||||
{
|
||||
(value, other) = (other, value % other);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsEven(this ulong value)
|
||||
{
|
||||
return (value & 1) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is not evenly divisible by 2.
|
||||
/// </summary>
|
||||
/// <param name="value">The value whose parity to check.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if <paramref name="value" /> is not evenly divisible by 2, or <see langword="false" />
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
[Pure]
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsOdd(this ulong value)
|
||||
{
|
||||
return !value.IsEven();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the current value is a prime number.
|
||||
/// </summary>
|
||||
|
@ -18,13 +18,9 @@ public static class CharExtensions
|
||||
[MethodImpl(CompilerResources.MaxOptimization)]
|
||||
public static bool IsEmoji(this char value)
|
||||
{
|
||||
#if NET7_0_OR_GREATER
|
||||
Span<char> chars = stackalloc char[1];
|
||||
chars[0] = value;
|
||||
return EmojiRegex.Value.IsMatch(chars);
|
||||
#else
|
||||
return EmojiRegex.Value.IsMatch(value.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -101,11 +101,7 @@ public static class RuneExtensions
|
||||
default:
|
||||
string exceptionFormat = ExceptionMessages.UnexpectedRuneUtf8SequenceLength;
|
||||
string message = string.Format(CultureInfo.CurrentCulture, exceptionFormat, length);
|
||||
#if NET7_0_OR_GREATER
|
||||
throw new UnreachableException(message);
|
||||
#else
|
||||
throw new InvalidOperationException(message);
|
||||
#endif
|
||||
// dotcover enable
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0;net6.0</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
<Configuration>Release</Configuration>
|
||||
<OutputType>Exe</OutputType>
|
||||
<Optimize>true</Optimize>
|
||||
|
Loading…
Reference in New Issue
Block a user