diff --git a/src/Numerics.Tests/PrecisionTest.cs b/src/Numerics.Tests/PrecisionTest.cs
index 1b869947..e5f18611 100644
--- a/src/Numerics.Tests/PrecisionTest.cs
+++ b/src/Numerics.Tests/PrecisionTest.cs
@@ -28,6 +28,7 @@
//
using System;
+using System.Numerics;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests
@@ -1156,5 +1157,100 @@ namespace MathNet.Numerics.UnitTests
Assert.AreEqual(-1, double.NegativeInfinity.CompareTo(1.0, Precision.DoubleDecimalPlaces));
Assert.AreEqual(1, 1.0.CompareTo(double.NegativeInfinity, Precision.DoubleDecimalPlaces));
}
+
+ [Test]
+ [TestCase(100.3123, 3, 0)]
+ [TestCase(1100.6123, 3, 1000)]
+ [TestCase(1500.8123, 3, 2000)]
+ [TestCase(110003245.3123, 3, 110003000)]
+ [TestCase(110003245.3123, 1, 110003250)]
+ [TestCase(110003245.3123, -2, 110003245.31)]
+ [TestCase(110003245.3123, 0, 110003245)]
+ public void RoundAboveDecimal(decimal number, int digit, decimal expectedResult)
+ {
+ Assert.AreEqual(expectedResult, number.RoundAboveZero(digit));
+ }
+
+ [Test]
+ [TestCase(100.3123, 3, 0)]
+ [TestCase(1100.6123, 3, 1000)]
+ [TestCase(1500.8123, 3, 2000)]
+ [TestCase(110003245.3123, 3, 110003000)]
+ [TestCase(110003245.3123, 1, 110003250)]
+ [TestCase(110003245.3123, -2, 110003245.31)]
+ [TestCase(110003245.3123, 0, 110003245)]
+ public void RoundAboveDouble(double number, int digit, double expectedResult)
+ {
+ Assert.AreEqual(expectedResult,number.RoundAboveZero(digit));
+ }
+
+ [Test]
+ [TestCase(100.3123f, 3, 0f)]
+ [TestCase(1100.6123f, 3, 1000f)]
+ [TestCase(1500.8123f, 3, 2000f)]
+ [TestCase(11245.3123f, 3, 11000f)]
+ [TestCase(13245.3123f, 1, 13250f)]
+ [TestCase(13245.3123f, -2, 13245.31f)]
+ [TestCase(13245.3123f, 0, 13245f)]
+ public void RoundAboveFloat(float number, int digit, float expectedResult)
+ {
+ Assert.AreEqual(expectedResult,number.RoundAboveZero(digit));
+ }
+
+ [Test]
+ [TestCase(100, 3, 0)]
+ [TestCase(1100, 3, 1000)]
+ [TestCase(1500, 3, 2000)]
+ [TestCase(110003245, 3, 110003000)]
+ [TestCase(110003245, 1, 110003250)]
+ [TestCase(110003245, -2, 110003245)]
+ public void RoundAboveInt(int number, int digit, int expectedResult)
+ {
+ Assert.AreEqual(expectedResult,number.RoundAboveZero(digit));
+ }
+
+ [Test]
+ public void RoundAboveUint()
+ {
+ Assert.AreEqual(110003250,((uint)110003245).RoundAboveZero(1));
+ }
+
+
+ [Test]
+ public void RoundAboveUlong()
+ {
+ Assert.AreEqual(3250, ((ulong)3245).RoundAboveZero(1));
+ }
+
+ [Test]
+ [TestCase(110003245, 1, 110003250)]
+ public void RoundAboveLong(long number, int digit, int expectedResult)
+ {
+ Assert.AreEqual(expectedResult, number.RoundAboveZero(digit));
+ }
+
+ [Test]
+ public void RoundAboveShort()
+ {
+ Assert.AreEqual(3250, ((short)3245).RoundAboveZero(1));
+ }
+
+ [Test]
+ public void RoundAboveUshort()
+ {
+ Assert.AreEqual(3250,((ushort)3245).RoundAboveZero(1));
+ }
+
+ [Test]
+ public void RoundAboveBigInteger()
+ {
+ Assert.AreEqual(BigInteger.Zero,new BigInteger(100).RoundAboveZero(3));
+ Assert.AreEqual(new BigInteger(1000),new BigInteger(1100).RoundAboveZero(3));
+ Assert.AreEqual(new BigInteger(2000),new BigInteger(1500).RoundAboveZero(3));
+ Assert.AreEqual(new BigInteger(110003000), new BigInteger(110003245).RoundAboveZero(3));
+ Assert.AreEqual(new BigInteger(110003250), new BigInteger(110003245).RoundAboveZero(1));
+ Assert.AreEqual(new BigInteger(110003245), new BigInteger(110003245).RoundAboveZero(-2));
+ Assert.AreEqual(new BigInteger(110003245), new BigInteger(110003245).RoundAboveZero(0));
+ }
}
}
diff --git a/src/Numerics/Precision.cs b/src/Numerics/Precision.cs
index 544295a6..60106c31 100644
--- a/src/Numerics/Precision.cs
+++ b/src/Numerics/Precision.cs
@@ -28,6 +28,7 @@
//
using System;
+using System.Numerics;
using System.Runtime;
using System.Runtime.InteropServices;
@@ -744,6 +745,151 @@ namespace MathNet.Numerics
return eps;
}
+ ///
+ /// Round to the number closest to 10^powerDigits.
+ ///
+ /// Number to be rounded
+ /// For closest 1000 enter 3, 10^powerDigits. If lower then zero you will get decimal digits.
+ /// To round 123456789 to hundreds RoundAboveZero(123456789, 2) = 123456800
+ /// Rounded number
+ public static decimal RoundAboveZero(this decimal number, int powerDigits = 3)
+ {
+ if (powerDigits <= 0)
+ return Math.Round(number, powerDigits*-1,MidpointRounding.AwayFromZero);
+ return Math.Round(number / (decimal) Math.Pow(10, powerDigits),MidpointRounding.AwayFromZero) * (decimal) Math.Pow(10, powerDigits);
+ }
+
+ ///
+ /// Round to the number closest to 10^powerDigits.
+ ///
+ /// Number to be rounded
+ /// For closest 1000 enter 3, 10^powerDigits. If lower then zero you will get decimal digits.
+ /// To round 123456789 to hundreds RoundAboveZero(123456789, 2) = 123456800
+ /// Rounded number
+ public static double RoundAboveZero(this double number, int powerDigits = 3)
+ {
+ if (powerDigits <= 0)
+ return Math.Round(number, powerDigits*-1,MidpointRounding.AwayFromZero);
+ return Math.Round(number / Math.Pow(10, powerDigits),MidpointRounding.AwayFromZero) * Math.Pow(10, powerDigits);
+ }
+
+ ///
+ /// Round to the number closest to 10^powerDigits.
+ ///
+ /// Number to be rounded
+ /// For closest 1000 enter 3, 10^powerDigits. If lower then zero you will get decimal digits.
+ /// To round 123456789 to hundreds RoundAboveZero(123456789, 2) = 123456800
+ /// Rounded number
+ public static int RoundAboveZero(this int number, int powerDigits = 3)
+ {
+ if (powerDigits <= 0)
+ return number;
+ return (int) RoundAboveZero((decimal) number, powerDigits);
+ }
+
+ ///
+ /// Round to the number closest to 10^powerDigits.
+ ///
+ /// Number to be rounded
+ /// For closest 1000 enter 3, 10^powerDigits. If lower then zero you will get decimal digits.
+ /// To round 123456789 to hundreds RoundAboveZero(123456789, 2) = 123456800
+ /// Rounded number
+ public static uint RoundAboveZero(this uint number, int powerDigits = 3)
+ {
+ if (powerDigits <= 0)
+ return number;
+ return (uint) RoundAboveZero((decimal) number, powerDigits);
+ }
+
+ ///
+ /// Round to the number closest to 10^powerDigits.
+ ///
+ /// Number to be rounded
+ /// For closest 1000 enter 3, 10^powerDigits. If lower then zero you will get decimal digits.
+ /// To round 123456789 to hundreds RoundAboveZero(123456789, 2) = 123456800
+ /// Rounded number
+ public static ulong RoundAboveZero(this ulong number, int powerDigits = 3)
+ {
+ if (powerDigits <= 0)
+ return number;
+ return (ulong) RoundAboveZero((decimal) number, powerDigits);
+ }
+
+ ///
+ /// Round to the number closest to 10^powerDigits.
+ ///
+ /// Number to be rounded
+ /// For closest 1000 enter 3, 10^powerDigits. If lower then zero you will get decimal digits.
+ /// To round 123456789 to hundreds RoundAboveZero(123456789, 2) = 123456800
+ /// Rounded number
+ public static long RoundAboveZero(this long number, int powerDigits = 3)
+ {
+ if (powerDigits <= 0)
+ return number;
+ return (long) RoundAboveZero((decimal) number, powerDigits);
+ }
+
+ ///
+ /// Round to the number closest to 10^powerDigits.
+ ///
+ /// Number to be rounded
+ /// For closest 1000 enter 3, 10^powerDigits. If lower then zero you will get decimal digits.
+ /// To round 123456789 to hundreds RoundAboveZero(123456789, 2) = 123456800
+ /// Rounded number
+ public static short RoundAboveZero(this short number, int powerDigits = 3)
+ {
+ if (powerDigits <= 0)
+ return number;
+ return (short) RoundAboveZero((decimal) number, powerDigits);
+ }
+
+ ///
+ /// Round to the number closest to 10^powerDigits.
+ ///
+ /// Number to be rounded
+ /// For closest 1000 enter 3, 10^powerDigits. If lower then zero you will get decimal digits.
+ /// To round 123456789 to hundreds RoundAboveZero(123456789, 2) = 123456800
+ /// Rounded number
+ public static ushort RoundAboveZero(this ushort number, int powerDigits = 3)
+ {
+ if (powerDigits <= 0)
+ return number;
+ return (ushort) RoundAboveZero((decimal) number, powerDigits);
+ }
+
+
+ ///
+ /// Round to the number closest to 10^powerDigits.
+ ///
+ /// Number to be rounded
+ /// For closest 1000 enter 3, 10^powerDigits. If lower then zero you will get decimal digits.
+ /// To round 123456789 to hundreds RoundAboveZero(123456789, 2) = 123456800
+ /// Rounded number
+ public static float RoundAboveZero(this float number, int powerDigits = 3)
+ {
+ return (float) RoundAboveZero((decimal) number, powerDigits);
+ }
+
+ ///
+ /// Round to the number closest to 10^powerDigits.
+ ///
+ /// Number to be rounded
+ /// For closest 1000 enter 3, 10^powerDigits. If lower then zero you will get decimal digits.
+ /// To round 123456789 to hundreds RoundAboveZero(123456789, 2) = 123456800
+ /// Rounded number
+ public static BigInteger RoundAboveZero(this BigInteger number, int powerDigits = 3)
+ {
+ if (powerDigits <= 0)
+ return number;
+
+ var onelarger = number / BigInteger.Pow(10, powerDigits-1);
+ var divided = onelarger / 10;
+ var lastDigit = onelarger - divided * 10;
+ if (lastDigit >= 5)
+ divided += 1;
+ return divided * BigInteger.Pow(10, powerDigits);
+ }
+
///
/// Calculates the actual positive double precision machine epsilon - the smallest number that can be added to 1, yielding a results different than 1.
/// This is also known as unit roundoff error. According to the definition of Prof. Higham.