1
0
mirror of https://github.com/oliverbooth/X10D synced 2024-11-21 16:08:48 +00:00

Compare commits

...

3 Commits

Author SHA1 Message Date
c7e78f5d19
refactor: fix logic for IBinaryInteger<T>.Factorial
The algorithm now starts at IBinaryInteger<T>.MultiplicativeIdentity rather than IBinaryInteger<T>.One
2024-11-14 16:06:52 +00:00
024f6dbd7a
chore: bump to 4.1.0 2024-11-14 16:01:46 +00:00
b1c644dc47
refactor!: replace Product and RangeTo on int types with generic math 2024-11-14 16:01:11 +00:00
15 changed files with 89 additions and 725 deletions

View File

@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## 4.0.1 - [Unreleased]
### Changed
- X1OD: `IBinaryInteger<T>.Factorial` now starts at `IBinaryInteger<T>.MultiplicativeIdentity` not
`IBinaryInteger<T>.One`.
- X10D: Removed `byte.Product`, `short.Product`, `ushort.Product`, `int.Product`, `uint.Product`, `long.Product`,
and `ulong.Product`, in favour of `INumber<T>.Product`.
- X10D: Removed `byte.RangeTo`, `short.RangeTo`, `ushort.RangeTo`, `int.RangeTo`, `uint.RangeTo`, `long.RangeTo`,
and `ulong.RangeTo`, in favour of `INumber<T>.RangeTo`.
### Removed
- X10D: Removed `Span<T>.Split` for .NET 9.0 target due to conflicts with

View File

@ -8,7 +8,7 @@
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<DebugType>pdbonly</DebugType>
<DebugSymbols>true</DebugSymbols>
<VersionPrefix>4.0.0</VersionPrefix>
<VersionPrefix>4.1.0</VersionPrefix>
<Authors>Oliver Booth</Authors>
<Nullable>enable</Nullable>
<NeutralLanguage>en</NeutralLanguage>

View File

@ -43,7 +43,7 @@ internal class ByteTests
}
[Test]
public void RangeTo_Byte_ShouldYieldCorrectValues()
public void RangeTo_ShouldYieldCorrectValues()
{
const byte start = 1;
const byte end = 10;
@ -56,49 +56,4 @@ internal class ByteTests
Assert.That(current, Is.EqualTo(end));
}
[Test]
public void RangeTo_Int16_ShouldYieldCorrectValues()
{
const byte start = 1;
const short end = 10;
short current = 1;
foreach (short value in start.RangeTo(end))
{
Assert.That(value, Is.EqualTo(current++));
}
Assert.That(current, Is.EqualTo(end));
}
[Test]
public void RangeTo_Int32_ShouldYieldCorrectValues()
{
const byte start = 1;
const int end = 10;
int current = 1;
foreach (int value in start.RangeTo(end))
{
Assert.That(value, Is.EqualTo(current++));
}
Assert.That(current, Is.EqualTo(end));
}
[Test]
public void RangeTo_Int64_ShouldYieldCorrectValues()
{
const byte start = 1;
const long end = 10;
long current = 1;
foreach (long value in start.RangeTo(end))
{
Assert.That(value, Is.EqualTo(current++));
}
Assert.That(current, Is.EqualTo(end));
}
}

View File

@ -46,7 +46,7 @@ internal class Int16Tests
}
[Test]
public void RangeTo_Int16_ShouldYieldCorrectValues()
public void RangeTo_ShouldYieldCorrectValues()
{
const short start = 1;
const short end = 10;
@ -60,36 +60,4 @@ internal class Int16Tests
Assert.That(current, Is.EqualTo(end));
}
[Test]
public void RangeTo_Int32_ShouldYieldCorrectValues()
{
const short start = 1;
const int end = 10;
var current = 1;
foreach (int value in start.RangeTo(end))
{
Assert.That(value, Is.EqualTo(current++));
}
Assert.That(current, Is.EqualTo(end));
}
[Test]
public void RangeTo_Int64_ShouldYieldCorrectValues()
{
const short start = 1;
const long end = 10;
long current = 1;
foreach (long value in start.RangeTo(end))
{
Assert.That(value, Is.EqualTo(current++));
}
Assert.That(current, Is.EqualTo(end));
}
}

View File

@ -50,7 +50,7 @@ internal class Int32Tests
}
[Test]
public void RangeTo_Int32_ShouldYieldCorrectValues()
public void RangeTo_ShouldYieldCorrectValues()
{
const int start = 1;
const int end = 10;
@ -64,18 +64,4 @@ internal class Int32Tests
Assert.That(current, Is.EqualTo(end));
}
[Test]
public void RangeTo_Int64_ShouldYieldCorrectValues()
{
const int start = 1;
const long end = 10;
long current = 1;
foreach (long value in start.RangeTo(end))
{
Assert.That(value, Is.EqualTo(current++));
}
Assert.That(current, Is.EqualTo(end));
}
}

View File

@ -51,7 +51,7 @@ internal class Int64Tests
}
[Test]
public void RangeTo_Int64_ShouldYieldCorrectValues()
public void RangeTo_ShouldYieldCorrectValues()
{
const long start = 1;
const long end = 10;

View File

@ -1,161 +0,0 @@
using System.Diagnostics.Contracts;
namespace X10D.Linq;
/// <summary>
/// LINQ-inspired extension methods for <see cref="IEnumerable{T}" /> of <see cref="byte" />.
/// </summary>
public static class ByteExtensions
{
/// <summary>
/// Computes the product of a sequence of <see cref="byte" /> values.
/// </summary>
/// <param name="source">A sequence of <see cref="byte" /> values that are used to calculate the product.</param>
/// <returns>The product the values in the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static byte Product(this IEnumerable<byte> source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Aggregate((byte)1, (current, value) => (byte)(current * value));
}
/// <summary>
/// Computes the product of a sequence of <see cref="sbyte" /> values.
/// </summary>
/// <param name="source">A sequence of <see cref="sbyte" /> values that are used to calculate the product.</param>
/// <returns>The product the values in the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
[CLSCompliant(false)]
public static sbyte Product(this IEnumerable<sbyte> source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Aggregate((sbyte)1, (current, value) => (sbyte)(current * value));
}
/// <summary>
/// Computes the product of a sequence of <see cref="byte" /> values that are obtained by invoking a transform function
/// on each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a product.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <returns>The product of the projected values.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static byte Product<TSource>(this IEnumerable<TSource> source, Func<TSource, byte> selector)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Select(selector).Product();
}
/// <summary>
/// Computes the product of a sequence of <see cref="sbyte" /> values that are obtained by invoking a transform function
/// on each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a product.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <returns>The product of the projected values.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
[CLSCompliant(false)]
public static sbyte Product<TSource>(this IEnumerable<TSource> source, Func<TSource, sbyte> selector)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Select(selector).Product();
}
/// <summary>
/// Returns an enumerable sequence of 8-bit integers ranging from the current value to a specified value.
/// </summary>
/// <param name="value">The starting value of the sequence.</param>
/// <param name="end">The ending value of the sequence.</param>
/// <returns>
/// An enumerable collection of 8-bit integers, ranging from <paramref name="value" /> to <paramref name="end" />.
/// </returns>
[Pure]
public static IEnumerable<byte> RangeTo(this byte value, byte end)
{
byte start = System.Math.Min(value, end);
end = System.Math.Max(value, end);
for (byte current = start; current < end; current++)
{
yield return current;
}
}
/// <summary>
/// Returns an enumerable sequence of 16-bit integers ranging from the current value to a specified value.
/// </summary>
/// <param name="value">The starting value of the sequence.</param>
/// <param name="end">The ending value of the sequence.</param>
/// <returns>
/// An enumerable collection of 16-bit integers, ranging from <paramref name="value" /> to <paramref name="end" />.
/// </returns>
[Pure]
public static IEnumerable<short> RangeTo(this byte value, short end)
{
short start = System.Math.Min(value, end);
end = System.Math.Max(value, end);
for (short current = start; current < end; current++)
{
yield return current;
}
}
/// <summary>
/// Returns an enumerable sequence of 32-bit integers ranging from the current value to a specified value.
/// </summary>
/// <param name="value">The starting value of the sequence.</param>
/// <param name="end">The ending value of the sequence.</param>
/// <returns>
/// An enumerable collection of 32-bit integers, ranging from <paramref name="value" /> to <paramref name="end" />.
/// </returns>
[Pure]
public static IEnumerable<int> RangeTo(this byte value, int end)
{
int start = System.Math.Min(value, end);
end = System.Math.Max(value, end);
for (int current = start; current < end; current++)
{
yield return current;
}
}
/// <summary>
/// Returns an enumerable sequence of 64-bit integers ranging from the current value to a specified value.
/// </summary>
/// <param name="value">The starting value of the sequence.</param>
/// <param name="end">The ending value of the sequence.</param>
/// <returns>
/// An enumerable collection of 64-bit integers, ranging from <paramref name="value" /> to <paramref name="end" />.
/// </returns>
[Pure]
public static IEnumerable<long> RangeTo(this byte value, long end)
{
long start = System.Math.Min(value, end);
end = System.Math.Max(value, end);
for (long current = start; current < end; current++)
{
yield return current;
}
}
}

View File

@ -1,42 +0,0 @@
namespace X10D.Linq;
/// <summary>
/// LINQ-inspired extension methods for <see cref="IEnumerable{T}" /> of <see cref="decimal" />.
/// </summary>
public static class DecimalExtensions
{
/// <summary>
/// Computes the product of a sequence of <see cref="decimal" /> values.
/// </summary>
/// <param name="source">A sequence of <see cref="decimal" /> values that are used to calculate the product.</param>
/// <returns>The product the values in the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static decimal Product(this IEnumerable<decimal> source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Aggregate(1m, (current, value) => (current * value));
}
/// <summary>
/// Computes the product of a sequence of <see cref="decimal" /> values that are obtained by invoking a transform function
/// on each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a product.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <returns>The product of the projected values.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static decimal Product<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Select(selector).Product();
}
}

View File

@ -1,42 +0,0 @@
namespace X10D.Linq;
/// <summary>
/// LINQ-inspired extension methods for <see cref="IEnumerable{T}" /> of <see cref="double" />.
/// </summary>
public static class DoubleExtensions
{
/// <summary>
/// Computes the product of a sequence of <see cref="double" /> values.
/// </summary>
/// <param name="source">A sequence of <see cref="double" /> values that are used to calculate the product.</param>
/// <returns>The product the values in the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static double Product(this IEnumerable<double> source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Aggregate(1.0, (current, value) => (current * value));
}
/// <summary>
/// Computes the product of a sequence of <see cref="double" /> values that are obtained by invoking a transform function
/// on each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a product.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <returns>The product of the projected values.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static double Product<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Select(selector).Product();
}
}

View File

@ -1,117 +0,0 @@
using System.Diagnostics.Contracts;
namespace X10D.Linq;
/// <summary>
/// LINQ-inspired extension methods for <see cref="IEnumerable{T}" /> of <see cref="long" />.
/// </summary>
public static class Int16Extensions
{
/// <summary>
/// Computes the product of a sequence of <see cref="short" /> values.
/// </summary>
/// <param name="source">A sequence of <see cref="short" /> values that are used to calculate the product.</param>
/// <returns>The product the values in the sequence.</returns>
public static short Product(this IEnumerable<short> source)
{
return source.Aggregate((short)1, (current, value) => (short)(current * value));
}
/// <summary>
/// Computes the product of a sequence of <see cref="ushort" /> values.
/// </summary>
/// <param name="source">A sequence of <see cref="ushort" /> values that are used to calculate the product.</param>
/// <returns>The product the values in the sequence.</returns>
[CLSCompliant(false)]
public static ushort Product(this IEnumerable<ushort> source)
{
return source.Aggregate((ushort)1, (current, value) => (ushort)(current * value));
}
/// <summary>
/// Computes the product of a sequence of <see cref="short" /> values that are obtained by invoking a transform function
/// on each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a product.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <returns>The product of the projected values.</returns>
public static short Product<TSource>(this IEnumerable<TSource> source, Func<TSource, short> selector)
{
return source.Select(selector).Product();
}
/// <summary>
/// Computes the product of a sequence of <see cref="ushort" /> values that are obtained by invoking a transform function
/// on each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a product.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <returns>The product of the projected values.</returns>
[CLSCompliant(false)]
public static ushort Product<TSource>(this IEnumerable<TSource> source, Func<TSource, ushort> selector)
{
return source.Select(selector).Product();
}
/// <summary>
/// Returns an enumerable sequence of 16-bit integers ranging from the current value to a specified value.
/// </summary>
/// <param name="value">The starting value of the sequence.</param>
/// <param name="end">The ending value of the sequence.</param>
/// <returns>
/// An enumerable collection of 16-bit integers, ranging from <paramref name="value" /> to <paramref name="end" />.
/// </returns>
[Pure]
public static IEnumerable<short> RangeTo(this short value, short end)
{
short start = System.Math.Min(value, end);
end = System.Math.Max(value, end);
for (short current = start; current < end; current++)
{
yield return current;
}
}
/// <summary>
/// Returns an enumerable sequence of 32-bit integers ranging from the current value to a specified value.
/// </summary>
/// <param name="value">The starting value of the sequence.</param>
/// <param name="end">The ending value of the sequence.</param>
/// <returns>
/// An enumerable collection of 32-bit integers, ranging from <paramref name="value" /> to <paramref name="end" />.
/// </returns>
[Pure]
public static IEnumerable<int> RangeTo(this short value, int end)
{
int start = System.Math.Min(value, end);
end = System.Math.Max(value, end);
for (int current = start; current < end; current++)
{
yield return current;
}
}
/// <summary>
/// Returns an enumerable sequence of 64-bit integers ranging from the current value to a specified value.
/// </summary>
/// <param name="value">The starting value of the sequence.</param>
/// <param name="end">The ending value of the sequence.</param>
/// <returns>
/// An enumerable collection of 64-bit integers, ranging from <paramref name="value" /> to <paramref name="end" />.
/// </returns>
[Pure]
public static IEnumerable<long> RangeTo(this short value, long end)
{
long start = System.Math.Min(value, end);
end = System.Math.Max(value, end);
for (long current = start; current < end; current++)
{
yield return current;
}
}
}

View File

@ -1,121 +0,0 @@
using System.Diagnostics.Contracts;
namespace X10D.Linq;
/// <summary>
/// LINQ-inspired extension methods for <see cref="IEnumerable{T}" /> of <see cref="int" />.
/// </summary>
public static class Int32Extensions
{
/// <summary>
/// Computes the product of a sequence of <see cref="int" /> values.
/// </summary>
/// <param name="source">A sequence of <see cref="int" /> values that are used to calculate the product.</param>
/// <returns>The product the values in the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static int Product(this IEnumerable<int> source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Aggregate(1, (current, value) => current * value);
}
/// <summary>
/// Computes the product of a sequence of <see cref="uint" /> values.
/// </summary>
/// <param name="source">A sequence of <see cref="uint" /> values that are used to calculate the product.</param>
/// <returns>The product the values in the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
[CLSCompliant(false)]
public static uint Product(this IEnumerable<uint> source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Aggregate(1u, (current, value) => current * value);
}
/// <summary>
/// Computes the product of a sequence of <see cref="int" /> values that are obtained by invoking a transform function on
/// each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a product.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <returns>The product of the projected values.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static int Product<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Select(selector).Product();
}
/// <summary>
/// Computes the product of a sequence of <see cref="uint" /> values that are obtained by invoking a transform function on
/// each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a product.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <returns>The product of the projected values.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
[CLSCompliant(false)]
public static uint Product<TSource>(this IEnumerable<TSource> source, Func<TSource, uint> selector)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Select(selector).Product();
}
/// <summary>
/// Returns an enumerable sequence of 32-bit integers ranging from the current value to a specified value.
/// </summary>
/// <param name="value">The starting value of the sequence.</param>
/// <param name="end">The ending value of the sequence.</param>
/// <returns>
/// An enumerable collection of 32-bit integers, ranging from <paramref name="value" /> to <paramref name="end" />.
/// </returns>
[Pure]
public static IEnumerable<int> RangeTo(this int value, int end)
{
int start = System.Math.Min(value, end);
end = System.Math.Max(value, end);
for (int current = start; current < end; current++)
{
yield return current;
}
}
/// <summary>
/// Returns an enumerable sequence of 64-bit integers ranging from the current value to a specified value.
/// </summary>
/// <param name="value">The starting value of the sequence.</param>
/// <param name="end">The ending value of the sequence.</param>
/// <returns>
/// An enumerable collection of 64-bit integers, ranging from <paramref name="value" /> to <paramref name="end" />.
/// </returns>
[Pure]
public static IEnumerable<long> RangeTo(this int value, long end)
{
long start = System.Math.Min(value, end);
end = System.Math.Max(value, end);
for (long current = start; current < end; current++)
{
yield return current;
}
}
}

View File

@ -1,101 +0,0 @@
using System.Diagnostics.Contracts;
namespace X10D.Linq;
/// <summary>
/// LINQ-inspired extension methods for <see cref="IEnumerable{T}" /> of <see cref="long" />.
/// </summary>
public static class Int64Extensions
{
/// <summary>
/// Computes the product of a sequence of <see cref="long" /> values.
/// </summary>
/// <param name="source">A sequence of <see cref="long" /> values that are used to calculate the product.</param>
/// <returns>The product the values in the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static long Product(this IEnumerable<long> source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Aggregate(1L, (current, value) => current * value);
}
/// <summary>
/// Computes the product of a sequence of <see cref="ulong" /> values.
/// </summary>
/// <param name="source">A sequence of <see cref="ulong" /> values that are used to calculate the product.</param>
/// <returns>The product the values in the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
[CLSCompliant(false)]
public static ulong Product(this IEnumerable<ulong> source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Aggregate(1UL, (current, value) => current * value);
}
/// <summary>
/// Computes the product of a sequence of <see cref="long" /> values that are obtained by invoking a transform function on
/// each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a product.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <returns>The product of the projected values.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static long Product<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Select(selector).Product();
}
/// <summary>
/// Computes the product of a sequence of <see cref="ulong" /> values that are obtained by invoking a transform function
/// on each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a product.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <returns>The product of the projected values.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
[CLSCompliant(false)]
public static ulong Product<TSource>(this IEnumerable<TSource> source, Func<TSource, ulong> selector)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Select(selector).Product();
}
/// <summary>
/// Returns an enumerable sequence of 64-bit integers ranging from the current value to a specified value.
/// </summary>
/// <param name="value">The starting value of the sequence.</param>
/// <param name="end">The ending value of the sequence.</param>
/// <returns>
/// An enumerable collection of 64-bit integers, ranging from <paramref name="value" /> to <paramref name="end" />.
/// </returns>
[Pure]
public static IEnumerable<long> RangeTo(this long value, long end)
{
long start = System.Math.Min(value, end);
end = System.Math.Max(value, end);
for (long current = start; current < end; current++)
{
yield return current;
}
}
}

View File

@ -0,0 +1,72 @@
using System.Diagnostics.Contracts;
using System.Numerics;
namespace X10D.Linq;
/// <summary>
/// LINQ-inspired extension methods for <see cref="IEnumerable{T}" /> of <see cref="INumber{TSelf}" />.
/// </summary>
public static class NumberExtensions
{
/// <summary>
/// Computes the product of a sequence of <see cref="INumber{TSelf}" /> values.
/// </summary>
/// <param name="source">A sequence of <see cref="int" /> values that are used to calculate the product.</param>
/// <typeparam name="TNumber">The type of the number for which to compute the product.</typeparam>
/// <returns>The product the values in the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static TNumber Product<TNumber>(this IEnumerable<TNumber> source)
where TNumber : INumber<TNumber>
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Aggregate(TNumber.MultiplicativeIdentity, (current, value) => current * value);
}
/// <summary>
/// Computes the product of a sequence of <see cref="INumber{TSelf}" /> values that are obtained by invoking a transform
/// function on each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a product.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <typeparam name="TNumber">The type of the number for which to compute the product.</typeparam>
/// <returns>The product of the projected values.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static TNumber Product<TSource, TNumber>(this IEnumerable<TSource> source, Func<TSource, TNumber> selector)
where TNumber : INumber<TNumber>
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Select(selector).Product();
}
/// <summary>
/// Returns an enumerable sequence of numbers ranging from the current value to a specified value.
/// </summary>
/// <param name="value">The starting value of the sequence.</param>
/// <param name="end">The ending value of the sequence.</param>
/// <typeparam name="TNumber">The type of the number for which to compute the product.</typeparam>
/// <returns>
/// An enumerable collection of <typeparamref name="TNumber"/>, ranging from <paramref name="value" /> to
/// <paramref name="end" />.
/// </returns>
[Pure]
public static IEnumerable<TNumber> RangeTo<TNumber>(this TNumber value, TNumber end)
where TNumber : INumber<TNumber>
{
TNumber start = TNumber.Min(value, end);
end = TNumber.Max(value, end);
for (TNumber current = start; current < end; current++)
{
yield return current;
}
}
}

View File

@ -1,42 +0,0 @@
namespace X10D.Linq;
/// <summary>
/// LINQ-inspired extension methods for <see cref="IEnumerable{T}" /> of <see cref="float" />.
/// </summary>
public static class SingleExtensions
{
/// <summary>
/// Computes the product of a sequence of <see cref="float" /> values.
/// </summary>
/// <param name="source">A sequence of <see cref="float" /> values that are used to calculate the product.</param>
/// <returns>The product the values in the sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static float Product(this IEnumerable<float> source)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Aggregate(1f, (current, value) => (current * value));
}
/// <summary>
/// Computes the product of a sequence of <see cref="float" /> values that are obtained by invoking a transform function
/// on each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a product.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <returns>The product of the projected values.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
public static float Product<TSource>(this IEnumerable<TSource> source, Func<TSource, float> selector)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
return source.Select(selector).Product();
}
}

View File

@ -69,13 +69,13 @@ public static class BinaryIntegerExtensions
return 1;
}
var result = 1L;
TInteger result = TInteger.MultiplicativeIdentity;
for (TInteger i = TInteger.One; i <= value; i++)
{
result *= long.CreateChecked(i);
result *= i;
}
return result;
return long.CreateChecked(result);
}
/// <summary>