Skip to content

Commit 863bdd1

Browse files
author
Oren (electricessence)
committed
Inspection fixes and optimizations.
1 parent 4e6014f commit 863bdd1

File tree

5 files changed

+152
-90
lines changed

5 files changed

+152
-90
lines changed

DynamicArithmetic.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ public static T PowerOf<T>(this T a, uint power)
5050
var result = a;
5151

5252
for (uint i = 1; i < power; i++)
53+
// ReSharper disable once RedundantCast
5354
result *= (dynamic)a;
5455

55-
return a;
56+
return result;
5657
}
5758

5859

MathExtensions.cs

Lines changed: 114 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
using System;
77
using System.Collections.Generic;
8+
using System.Diagnostics.Contracts;
89

910
namespace Open.Arithmetic
1011
{
@@ -14,51 +15,72 @@ public static class MathExtensions
1415
static void ValidateIntPower(int power)
1516
{
1617
if (power < 0)
17-
throw new ArgumentOutOfRangeException(nameof(power), power, "In order to maintain the interger math, power cannot be negative.");
18+
throw new ArgumentOutOfRangeException(nameof(power), power,
19+
"In order to maintain the interger math, power cannot be negative.");
1820
}
1921

2022
/// <summary>
2123
/// Raise a number to the power of another. Uses integer math only.
2224
/// </summary>
23-
/// <param name="value"></param>
24-
/// <param name="power"></param>
25+
/// <param name="base">The value to multiply.</param>
26+
/// <param name="power">The number of times to multiply by.</param>
2527
/// <returns>The value to the power.</returns>
26-
public static int PowerOf(this int value, int power)
28+
public static int PowerOf(this int @base, int power)
2729
{
2830
ValidateIntPower(power);
2931

30-
if (value == 0 || value == 1)
31-
return value;
32+
var result = 1;
33+
while (power != 0)
34+
{
35+
if ((power & 1) == 1)
36+
result *= @base;
37+
power >>= 1;
38+
@base *= @base;
39+
}
3240

33-
if (value == -1)
34-
return power % 2 == 0 ? 1 : -1;
41+
return result;
42+
}
3543

36-
var v = 1;
37-
for (var i = 1; i < power; i++)
38-
v *= value;
39-
return v;
44+
/// <summary>
45+
/// Raise a number to the power of another. Uses integer math only.
46+
/// </summary>
47+
/// <param name="base">The value to multiply.</param>
48+
/// <param name="power">The number of times to multiply by.</param>
49+
/// <returns>The value to the power.</returns>
50+
public static ulong PowerOf(this ulong @base, int power)
51+
{
52+
ulong result = 1;
53+
while (power != 0)
54+
{
55+
if ((power & 1) == 1)
56+
result *= @base;
57+
power >>= 1;
58+
@base *= @base;
59+
}
60+
61+
return result;
4062
}
4163

4264
/// <summary>
4365
/// Raise a number to the power of another. Uses integer math only.
4466
/// </summary>
45-
/// <param name="value"></param>
46-
/// <param name="power"></param>
67+
/// <param name="base">The value to multiply.</param>
68+
/// <param name="power">The number of times to multiply by.</param>
4769
/// <returns>The value to the power.</returns>
48-
public static long PowerOf(this long value, int power)
70+
public static long PowerOf(this long @base, int power)
4971
{
5072
ValidateIntPower(power);
5173

52-
if (value == 0L || value == 1L)
53-
return value;
54-
55-
if (value == -1L)
56-
return power % 2 == 0 ? 1L : -1L;
74+
long result = 1;
75+
while (power != 0)
76+
{
77+
if ((power & 1) == 1)
78+
result *= @base;
79+
power >>= 1;
80+
@base *= @base;
81+
}
5782

58-
var v = 1L;
59-
for (var i = 1; i < power; i++)
60-
v *= value;
61-
return v;
83+
return result;
6284
}
6385

6486
/// <summary>
@@ -69,7 +91,8 @@ public static long PowerOf(this long value, int power)
6991
public static int AsInteger(this bool[] source)
7092
{
7193
if (source == null) throw new NullReferenceException();
72-
if (source.Length > 32) throw new ArgumentOutOfRangeException("Array cannot be greater than 32 bits.");
94+
if (source.Length > 32) throw new ArgumentOutOfRangeException(nameof(source), source, "Array cannot be greater than 32 bits.");
95+
Contract.EndContractBlock();
7396

7497
var result = 0;
7598

@@ -81,14 +104,15 @@ public static int AsInteger(this bool[] source)
81104
}
82105

83106
/// <summary>
84-
/// Converts a set of booleans (0|1) to a 32 bit integer.
107+
/// Converts a set of booleans (0|1) to a 64 bit integer.
85108
/// </summary>
86-
/// <param name="source">A array of 32 booleans or less.</param>
87-
/// <returns>32 bit integer</returns>
109+
/// <param name="source">A array of 64 booleans or less.</param>
110+
/// <returns>64 bit integer</returns>
88111
public static long AsLong(this bool[] source)
89112
{
90113
if (source == null) throw new NullReferenceException();
91-
if (source.Length > 64) throw new ArgumentOutOfRangeException("Array cannot be greater than 32 bits.");
114+
if (source.Length > 64) throw new ArgumentOutOfRangeException(nameof(source), source, "Array cannot be greater than 64 bits.");
115+
Contract.EndContractBlock();
92116

93117
long result = 0;
94118

@@ -99,10 +123,18 @@ public static long AsLong(this bool[] source)
99123
return result;
100124
}
101125

102-
public static double Product(this IEnumerable<double> source)
126+
/// <summary>
127+
/// Multiplies a set of numbers together.
128+
/// </summary>
129+
/// <param name="source">The source enumerable.</param>
130+
/// <param name="defaultValueIfNoElements">The value to return if the sequence contains no elements.</param>
131+
/// <returns>The resultant product.</returns>
132+
public static double Product(this IEnumerable<double> source,
133+
double defaultValueIfNoElements = double.NaN)
103134
{
104-
105-
if (source == null) throw new NullReferenceException();
135+
if (source == null)
136+
throw new NullReferenceException();
137+
Contract.EndContractBlock();
106138

107139
var any = false;
108140
var result = 1d;
@@ -113,13 +145,24 @@ public static double Product(this IEnumerable<double> source)
113145
result *= s;
114146
}
115147

116-
return any ? result : double.NaN;
148+
return any ? result : defaultValueIfNoElements;
117149
}
118150

119-
public static double AverageDouble(this IEnumerable<double> source)
151+
/// <summary>
152+
/// Sums all the values of the sequence and divides by the count of the elements. (The average of the sequence.)
153+
/// </summary>
154+
/// <param name="source">The source enumerable.</param>
155+
/// <param name="defaultValueIfNoElements">The value to return if the sequence contains no elements.</param>
156+
/// <returns>The resultant average of the sequence.</returns>
157+
public static double AverageDouble(this IEnumerable<double> source,
158+
double defaultValueIfNoElements = double.NaN)
120159
{
160+
if (source == null)
161+
throw new NullReferenceException();
162+
Contract.EndContractBlock();
163+
121164
double sum = 0;
122-
double count = 0;
165+
var count = 0;
123166
foreach (var s in source)
124167
{
125168
if (double.IsNaN(s))
@@ -129,28 +172,40 @@ public static double AverageDouble(this IEnumerable<double> source)
129172
}
130173

131174
if (count == 0)
132-
return double.NaN;
175+
return defaultValueIfNoElements;
133176

134177
return sum / count;
135178
}
136179

180+
/// <summary>
181+
/// Takes the first element in the sequence and divides it by the following elements.
182+
/// </summary>
183+
/// <param name="source">The source enumerable.</param>
184+
/// <returns>The resultant quotiient.</returns>
137185
public static double Quotient(this IEnumerable<double> source)
138186
{
139-
if (source == null) throw new NullReferenceException();
187+
if (source == null)
188+
throw new NullReferenceException();
189+
Contract.EndContractBlock();
140190

141191
var index = 0;
142192
var result = double.NaN;
143193
foreach (var s in source)
144194
{
145195
if (double.IsNaN(s)) return double.NaN;
146-
if (index == 0)
147-
{
148-
if (s == 0) return 0;
149-
result = s;
150-
}
151-
else
196+
switch (index)
152197
{
153-
result /= s;
198+
// ReSharper disable once CompareOfFloatsByEqualityOperator
199+
case 0 when s == 0:
200+
return 0;
201+
case 0:
202+
result = s;
203+
break;
204+
default:
205+
// ReSharper disable once CompareOfFloatsByEqualityOperator
206+
if (s == 0) return double.NaN;
207+
result /= s;
208+
break;
154209
}
155210

156211
index++;
@@ -159,12 +214,27 @@ public static double Quotient(this IEnumerable<double> source)
159214
return result;
160215
}
161216

217+
/// <summary>
218+
/// Takes the numerator and divides it by the divisors.
219+
/// </summary>
220+
/// <param name="divisors">The source enumerable.</param>
221+
/// <param name="numerator">The value to divide.</param>
222+
/// <returns>The resultant quotient.</returns>
162223
public static double QuotientOf(this IEnumerable<double> divisors, double numerator)
163224
{
225+
if (divisors == null)
226+
throw new NullReferenceException();
227+
Contract.EndContractBlock();
228+
229+
// ReSharper disable once CompareOfFloatsByEqualityOperator
230+
if (double.IsNaN(numerator) || double.IsInfinity(numerator) || numerator == 0)
231+
return numerator;
232+
164233
var any = false;
165234
var result = numerator;
166235
foreach (var s in divisors)
167236
{
237+
// ReSharper disable once CompareOfFloatsByEqualityOperator
168238
if (s == 0 || double.IsNaN(s)) return double.NaN;
169239
result /= s;
170240
any = true;
@@ -173,27 +243,6 @@ public static double QuotientOf(this IEnumerable<double> divisors, double numera
173243
return any ? result : double.NaN;
174244
}
175245

176-
public static double Difference(this IEnumerable<double> source)
177-
{
178-
if (source == null) throw new NullReferenceException();
179-
180-
var any = false;
181-
var result = 0d;
182-
foreach (var s in source)
183-
{
184-
if (double.IsNaN(s)) return double.NaN;
185-
if (!any)
186-
result = s;
187-
else
188-
result -= s;
189-
190-
any = true;
191-
192-
}
193-
194-
return any ? result : double.NaN;
195-
}
196-
197246

198247
}
199248
}

Open.Arithmetic.csproj

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ Part of the "Open" set of libraries.</Description>
1515
<RepositoryUrl>https://github.com/electricessence/Open.Arithmetic/</RepositoryUrl>
1616
<RepositoryType>git</RepositoryType>
1717
<PackageTags>dotnet, dotnet-core, dotnetcore, cs, math, dynamic, arithmetic, triangular, statistical, variance, covariance, correlation</PackageTags>
18-
<Version>1.1.1</Version>
19-
<PackageReleaseNotes>Extends Triangular methods and added TriangularIndexer.</PackageReleaseNotes>
20-
<AssemblyVersion>1.1.1.0</AssemblyVersion>
21-
<FileVersion>1.1.1.0</FileVersion>
18+
<Version>1.2.0</Version>
19+
<PackageReleaseNotes>Inspection fixes and optimizations.</PackageReleaseNotes>
20+
<AssemblyVersion>1.2.0.0</AssemblyVersion>
21+
<FileVersion>1.2.0.0</FileVersion>
2222
</PropertyGroup>
2323

2424
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
@@ -37,7 +37,8 @@ Part of the "Open" set of libraries.</Description>
3737
</ItemGroup>
3838

3939
<ItemGroup>
40-
<PackageReference Include="Open.Collections" Version="2.3.0" />
40+
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
41+
<PackageReference Include="Open.Collections" Version="2.4.4" />
4142
</ItemGroup>
4243

4344
</Project>

0 commit comments

Comments
 (0)