Skip to content

Commit

Permalink
Merge pull request #1310 from Bykiev/FixRoundDown
Browse files Browse the repository at this point in the history
Fix ROUNDDOWN function
  • Loading branch information
tonyqus committed May 2, 2024
2 parents 31d087c + 6ae51ea commit e7067a7
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 48 deletions.
2 changes: 1 addition & 1 deletion main/NPOI.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<ItemGroup>
<PackageReference Include="Enums.NET" Version="4.0.1" />
<PackageReference Include="ExtendedNumerics.BigDecimal" Version="2023.1000.0.230" />
<PackageReference Include="ExtendedNumerics.BigDecimal" Version="2025.1000.2.122" />
<PackageReference Include="MathNet.Numerics.Signed" Version="5.0.0" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.0" />
<PackageReference Include="BouncyCastle.Cryptography" Version="2.3.0" />
Expand Down
95 changes: 48 additions & 47 deletions main/SS/Formula/Functions/MathX.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*/
namespace NPOI.SS.Formula.Functions
{
using ExtendedNumerics;
using System;

/**
Expand Down Expand Up @@ -54,24 +55,24 @@ public static double Round(double n, int p)
{
double retval;

if (double.IsNaN(n) || double.IsInfinity(n))
if(double.IsNaN(n) || double.IsInfinity(n))
{
retval = double.NaN;
}
else if (double.MaxValue == n)
else if(double.MaxValue == n)
return double.MaxValue;
else if (double.MinValue == n)
else if(double.MinValue == n)
return 0;
else
{
if (p >= 0)
if(p >= 0)
{
retval = (double)Math.Round((decimal)n, p, MidpointRounding.AwayFromZero);
retval = (double) Math.Round((decimal) n, p, MidpointRounding.AwayFromZero);
}
else
{
int temp = (int)Math.Pow(10, Math.Abs(p));
retval = (double)(Math.Round((decimal)(n) / temp, MidpointRounding.AwayFromZero) * temp);
retval = (double) (Math.Round((decimal) (n) / temp, MidpointRounding.AwayFromZero) * temp);
}
}

Expand All @@ -97,16 +98,16 @@ public static double RoundUp(double n, int p)
{
double retval;

if (double.IsNaN(n) || double.IsInfinity(n))
if(double.IsNaN(n) || double.IsInfinity(n))
{
retval = double.NaN;
}
else if (double.MaxValue == n)
else if(double.MaxValue == n)
return double.MaxValue;
else if (double.MinValue == n)
else if(double.MinValue == n)
{
double digit = 1;
while (p > 0)
while(p > 0)
{
digit = digit / 10;
p--;
Expand All @@ -115,23 +116,23 @@ public static double RoundUp(double n, int p)
}
else
{
if (p != 0)
if(p != 0)
{
double temp = Math.Pow(10, p);
double nat = (double)((decimal)Math.Abs(n * temp));

retval = Sign(n) *
((nat == (long)nat)
((nat == (long) nat)
? nat / temp
: Math.Round(nat + 0.5) / temp);
}
else
{
double na = Math.Abs(n);
retval = Sign(n) *
((na == (long)na)
((na == (long) na)
? na
: (long)na + 1);
: (long) na + 1);
}
}

Expand All @@ -157,24 +158,24 @@ public static double RoundDown(double n, int p)
{
double retval;

if (double.IsNaN(n) || double.IsInfinity(n))
if(double.IsNaN(n) || double.IsInfinity(n))
{
retval = double.NaN;
}
else if (double.MaxValue == n)
else if(double.MaxValue == n)
return double.MaxValue;
else if (double.MinValue == n)
else if(double.MinValue == n)
return 0;
else
{
if (p != 0)
if(p != 0)
{
double temp = Math.Pow(10, p);
retval = Sign(n) * Math.Round((Math.Abs(n) * temp) - 0.5, MidpointRounding.AwayFromZero) / temp;
var value = new BigDecimal(n);
retval = (double)BigDecimal.Round(value, p);
}
else
{
retval = (long)n;
retval = (long) n;
}
}

Expand All @@ -194,7 +195,7 @@ public static double RoundDown(double n, int p)
*/
public static short Sign(double d)
{
return (short)((d == 0)
return (short) ((d == 0)
? 0
: (d < 0)
? -1
Expand All @@ -209,7 +210,7 @@ public static double Average(double[] values)
{
double ave = 0;
double sum = 0;
for (int i = 0, iSize = values.Length; i < iSize; i++)
for(int i = 0, iSize = values.Length; i < iSize; i++)
{
sum += values[i];
}
Expand All @@ -225,7 +226,7 @@ public static double Average(double[] values)
public static double Sum(double[] values)
{
double sum = 0;
for (int i = 0, iSize = values.Length; i < iSize; i++)
for(int i = 0, iSize = values.Length; i < iSize; i++)
{
sum += values[i];
}
Expand All @@ -239,7 +240,7 @@ public static double Sum(double[] values)
public static double Sumsq(double[] values)
{
double sumsq = 0;
for (int i = 0, iSize = values.Length; i < iSize; i++)
for(int i = 0, iSize = values.Length; i < iSize; i++)
{
sumsq += values[i] * values[i];
}
Expand All @@ -254,10 +255,10 @@ public static double Sumsq(double[] values)
public static double Product(double[] values)
{
double product = 0;
if (values != null && values.Length > 0)
if(values != null && values.Length > 0)
{
product = 1;
for (int i = 0, iSize = values.Length; i < iSize; i++)
for(int i = 0, iSize = values.Length; i < iSize; i++)
{
product *= values[i];
}
Expand All @@ -273,7 +274,7 @@ public static double Product(double[] values)
public static double Min(double[] values)
{
double min = double.PositiveInfinity;
for (int i = 0, iSize = values.Length; i < iSize; i++)
for(int i = 0, iSize = values.Length; i < iSize; i++)
{
min = Math.Min(min, values[i]);
}
Expand All @@ -288,7 +289,7 @@ public static double Min(double[] values)
public static double Max(double[] values)
{
double max = double.NegativeInfinity;
for (int i = 0, iSize = values.Length; i < iSize; i++)
for(int i = 0, iSize = values.Length; i < iSize; i++)
{
max = Math.Max(max, values[i]);
}
Expand All @@ -314,7 +315,7 @@ public static double Floor(double n, double s)
{
double f;

if ((n < 0 && s > 0) || (n > 0 && s < 0) || (s == 0 && n != 0))
if((n < 0 && s > 0) || (n > 0 && s < 0) || (s == 0 && n != 0))
{
f = double.NaN;
}
Expand Down Expand Up @@ -345,7 +346,7 @@ public static double Ceiling(double n, double s)
{
double c;

if (n > 0 && s < 0)
if(n > 0 && s < 0)
{
c = double.NaN;
}
Expand All @@ -371,11 +372,11 @@ public static double Factorial(int n)
{
double d = 1;

if (n >= 0)
if(n >= 0)
{
if (n <= 170)
if(n <= 170)
{
for (int i = 1; i <= n; i++)
for(int i = 1; i <= n; i++)
{
d *= i;
}
Expand Down Expand Up @@ -412,11 +413,11 @@ public static double Mod(double n, double d)
{
double result = 0;

if (d == 0)
if(d == 0)
{
result = double.NaN;
}
else if (Sign(n) == Sign(d))
else if(Sign(n) == Sign(d))
{
//double t = Math.Abs(n / d);
//t = t - (long)t;
Expand Down Expand Up @@ -516,17 +517,17 @@ public static double SumProduct(double[][] arrays)
int narr = arrays.Length;
int arrlen = arrays[0].Length;

for (int j = 0; j < arrlen; j++)
for(int j = 0; j < arrlen; j++)
{
double t = 1;
for (int i = 0; i < narr; i++)
for(int i = 0; i < narr; i++)
{
t *= arrays[i][j];
}
d += t;
}
}
catch (IndexOutOfRangeException)
catch(IndexOutOfRangeException)
{
d = double.NaN;
}
Expand All @@ -551,12 +552,12 @@ public static double Sumx2my2(double[] xarr, double[] yarr)

try
{
for (int i = 0, iSize = xarr.Length; i < iSize; i++)
for(int i = 0, iSize = xarr.Length; i < iSize; i++)
{
d += (xarr[i] + yarr[i]) * (xarr[i] - yarr[i]);
}
}
catch (IndexOutOfRangeException)
catch(IndexOutOfRangeException)
{
d = double.NaN;
}
Expand All @@ -581,12 +582,12 @@ public static double Sumx2py2(double[] xarr, double[] yarr)

try
{
for (int i = 0, iSize = xarr.Length; i < iSize; i++)
for(int i = 0, iSize = xarr.Length; i < iSize; i++)
{
d += (xarr[i] * xarr[i]) + (yarr[i] * yarr[i]);
}
}
catch (IndexOutOfRangeException )
catch(IndexOutOfRangeException)
{
d = double.NaN;
}
Expand All @@ -612,13 +613,13 @@ public static double Sumxmy2(double[] xarr, double[] yarr)

try
{
for (int i = 0, iSize = xarr.Length; i < iSize; i++)
for(int i = 0, iSize = xarr.Length; i < iSize; i++)
{
double t = (xarr[i] - yarr[i]);
d += t * t;
}
}
catch (IndexOutOfRangeException )
catch(IndexOutOfRangeException)
{
d = double.NaN;
}
Expand All @@ -639,15 +640,15 @@ public static double Sumxmy2(double[] xarr, double[] yarr)
public static double NChooseK(int n, int k)
{
double d = 1;
if (n < 0 || k < 0 || n < k)
if(n < 0 || k < 0 || n < k)
{
d = double.NaN;
}
else
{
int minnk = Math.Min(n - k, k);
int maxnk = Math.Max(n - k, k);
for (int i = maxnk; i < n; i++)
for(int i = maxnk; i < n; i++)
{
d *= i + 1;
}
Expand Down
6 changes: 6 additions & 0 deletions testcases/main/SS/Formula/Functions/TestMathX.cs
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,9 @@ public void TestRoundDown()
d = -123.99; p = 0;
AssertEquals("roundDown ", -123, MathX.RoundDown(d, p));

d = -123.99; p = 2;
AssertEquals("roundDown ", -123.99, MathX.RoundDown(d, p));

d = 123.99; p = 2;
AssertEquals("roundDown ", 123.99, MathX.RoundDown(d, p));

Expand Down Expand Up @@ -807,6 +810,9 @@ public void TestRoundDown()

d = Double.MinValue; p = 1;
AssertEquals("roundDown ", 0.0d, MathX.RoundDown(d, p));

d = 17.56; p = 2;
AssertEquals("roundDown ", 17.56, MathX.RoundDown(d, p));
}
[Test]
public void TestRoundUp()
Expand Down

0 comments on commit e7067a7

Please sign in to comment.