Index: Core/Common/src/Core.Common.Base/Data/RoundedDouble.cs =================================================================== diff -u -ra5b051a25a6bb059d5928e29a8d741a8ec31fcd5 -raf38c7a9724254095e2e3a631dd7e974465a1fb9 --- Core/Common/src/Core.Common.Base/Data/RoundedDouble.cs (.../RoundedDouble.cs) (revision a5b051a25a6bb059d5928e29a8d741a8ec31fcd5) +++ Core/Common/src/Core.Common.Base/Data/RoundedDouble.cs (.../RoundedDouble.cs) (revision af38c7a9724254095e2e3a631dd7e974465a1fb9) @@ -9,14 +9,15 @@ /// This class represents a that is being rounded to a certain /// number of places. /// - public sealed class RoundedDouble : IEquatable, IEquatable + public struct RoundedDouble : IEquatable, IEquatable { /// /// The maximum number of decimal places supported by this class. /// public const int MaximumNumberOfDecimalPlaces = 15; - private double value; + private readonly double value; + private readonly int numberOfDecimalPlaces; /// /// Initializes a new instance of the class with a @@ -31,30 +32,30 @@ { ValidateNumberOfDecimalPlaces(numberOfDecimalPlaces); - NumberOfDecimalPlaces = numberOfDecimalPlaces; - Value = value; + this.numberOfDecimalPlaces = numberOfDecimalPlaces; + this.value = RoundDouble(value, numberOfDecimalPlaces); } /// /// Gets the number of decimal places use to round to. /// - public int NumberOfDecimalPlaces { get; private set; } + public int NumberOfDecimalPlaces + { + get + { + return numberOfDecimalPlaces; + } + } /// - /// Gets or sets the value. + /// Gets the value. /// public double Value { get { return value; } - set - { - this.value = IsSpecialDoubleValue(value) ? - value : - ConvertIntoRoundedDouble(value); - } } public static bool operator ==(RoundedDouble left, RoundedDouble right) @@ -77,16 +78,27 @@ return new RoundedDouble(MaximumNumberOfDecimalPlaces, d); } + /// + /// Converts this value to another but with the givenTo the precision + /// number of decimal places instead. + /// + /// The new number of decimal places. + /// The converted . + public RoundedDouble ToPrecision(int newNumberOfDecimalPlaces) + { + if (newNumberOfDecimalPlaces == NumberOfDecimalPlaces) + { + return this; + } + return new RoundedDouble(newNumberOfDecimalPlaces, value); + } + public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) { return false; } - if (ReferenceEquals(this, obj)) - { - return true; - } if (obj.GetType() != GetType()) { return false; @@ -119,17 +131,16 @@ public bool Equals(RoundedDouble other) { - if (ReferenceEquals(null, other)) - { - return false; - } - if (ReferenceEquals(this, other)) - { - return true; - } return Value.Equals(other.Value); } + private static double RoundDouble(double value, int numberOfDecimalPlaces) + { + return IsSpecialDoubleValue(value) ? + value : + Math.Round(value, numberOfDecimalPlaces, MidpointRounding.AwayFromZero); + } + /// /// Validates . /// @@ -159,10 +170,5 @@ { return "F" + NumberOfDecimalPlaces; } - - private double ConvertIntoRoundedDouble(double valueToConvert) - { - return Math.Round(valueToConvert, NumberOfDecimalPlaces, MidpointRounding.AwayFromZero); - } } } \ No newline at end of file Index: Core/Common/test/Core.Common.Base.Test/Data/RoundedDoubleTest.cs =================================================================== diff -u -ra5b051a25a6bb059d5928e29a8d741a8ec31fcd5 -raf38c7a9724254095e2e3a631dd7e974465a1fb9 --- Core/Common/test/Core.Common.Base.Test/Data/RoundedDoubleTest.cs (.../RoundedDoubleTest.cs) (revision a5b051a25a6bb059d5928e29a8d741a8ec31fcd5) +++ Core/Common/test/Core.Common.Base.Test/Data/RoundedDoubleTest.cs (.../RoundedDoubleTest.cs) (revision af38c7a9724254095e2e3a631dd7e974465a1fb9) @@ -117,10 +117,7 @@ double value, int numberOfDecimals, double expectedReturnValue) { // Setup - var roundedValue = new RoundedDouble(numberOfDecimals) - { - Value = value - }; + var roundedValue = new RoundedDouble(numberOfDecimals, value); // Call double returnValue = roundedValue.Value; @@ -164,10 +161,7 @@ double value, int numberOfDecimals, string expectedText) { // Setup - var roundedValue = new RoundedDouble(numberOfDecimals) - { - Value = value - }; + var roundedValue = new RoundedDouble(numberOfDecimals, value); // Call string text = roundedValue.ToString(); @@ -190,20 +184,6 @@ } [Test] - public void Equals_ToNullRoundedDouble_ReturnFalse() - { - // Setup - var roundedDouble = new RoundedDouble(2); - RoundedDouble nullValue = null; - - // Call - bool isEqual = roundedDouble.Equals(nullValue); - - // Assert - Assert.IsFalse(isEqual); - } - - [Test] public void Equals_ToSameInstance_ReturnTrue() { // Setup @@ -253,14 +233,8 @@ int numberOfPlaces, double value) { // Setup - var baseRoundedDouble = new RoundedDouble(3) - { - Value = 1.234 - }; - object comparisonRoundedDouble = new RoundedDouble(numberOfPlaces) - { - Value = value - }; + var baseRoundedDouble = new RoundedDouble(3, 1.234); + object comparisonRoundedDouble = new RoundedDouble(numberOfPlaces, value); // Call var isEqual1 = baseRoundedDouble.Equals(comparisonRoundedDouble); @@ -279,14 +253,8 @@ int numberOfPlaces, double value) { // Setup - var baseRoundedDouble = new RoundedDouble(3) - { - Value = 1.234 - }; - object comparisonRoundedDouble = new RoundedDouble(numberOfPlaces) - { - Value = value - }; + var baseRoundedDouble = new RoundedDouble(3, 1.234); + object comparisonRoundedDouble = new RoundedDouble(numberOfPlaces, value); // Call int hash1 = baseRoundedDouble.GetHashCode(); @@ -300,14 +268,8 @@ public void EqualityOperator_TwoUnequalRoundedValues_ReturnFalse() { // Setup - var roundedDouble1 = new RoundedDouble(2) - { - Value = 1.23 - }; - var roundedDouble2 = new RoundedDouble(1) - { - Value = 1.2 - }; + var roundedDouble1 = new RoundedDouble(2, 1.23); + var roundedDouble2 = new RoundedDouble(1, 1.2); // Call var isEqual1 = roundedDouble1 == roundedDouble2; @@ -322,14 +284,8 @@ public void EqualityOperator_TwoEqualRoundedValues_ReturnFalse() { // Setup - var roundedDouble1 = new RoundedDouble(2) - { - Value = 1.20 - }; - var roundedDouble2 = new RoundedDouble(1) - { - Value = 1.2 - }; + var roundedDouble1 = new RoundedDouble(2, 1.20); + var roundedDouble2 = new RoundedDouble(1, 1.2); // Call var isEqual1 = roundedDouble1 == roundedDouble2; @@ -344,14 +300,8 @@ public void InequalityOperator_TwoUnequalRoundedValues_ReturnTrue() { // Setup - var roundedDouble1 = new RoundedDouble(2) - { - Value = 1.23 - }; - var roundedDouble2 = new RoundedDouble(1) - { - Value = 1.2 - }; + var roundedDouble1 = new RoundedDouble(2, 1.23); + var roundedDouble2 = new RoundedDouble(1, 1.2); // Precondition: Assert.IsFalse(roundedDouble1.Equals(roundedDouble2)); @@ -369,14 +319,8 @@ public void InequalityOperator_TwoEqualRoundedValues_ReturnFalse() { // Setup - var roundedDouble1 = new RoundedDouble(2) - { - Value = 1.20 - }; - var roundedDouble2 = new RoundedDouble(1) - { - Value = 1.2 - }; + var roundedDouble1 = new RoundedDouble(2, 1.20); + var roundedDouble2 = new RoundedDouble(1, 1.2); // Precondition: Assert.IsTrue(roundedDouble1.Equals(roundedDouble2)); @@ -397,10 +341,7 @@ double value, int numberOfDecimalPlaces) { // Setup - var roundedDouble = new RoundedDouble(numberOfDecimalPlaces) - { - Value = value - }; + var roundedDouble = new RoundedDouble(numberOfDecimalPlaces, value); // Call var isEqual1 = roundedDouble.Equals(value); @@ -418,10 +359,7 @@ double value, int numberOfDecimalPlaces) { // Setup - var roundedDouble = new RoundedDouble(numberOfDecimalPlaces) - { - Value = value - }; + var roundedDouble = new RoundedDouble(numberOfDecimalPlaces, value); // Call var isEqual1 = roundedDouble.Equals(value); @@ -436,10 +374,7 @@ public void Equals_RoundedDoubleTotallyDifferentFromDouble_ReturnFalse() { // Setup - var roundedDouble = new RoundedDouble(2) - { - Value = 1.23 - }; + var roundedDouble = new RoundedDouble(2, 1.23); double otherValue = 4.56; // Call @@ -456,10 +391,7 @@ { // Setup double otherValue = 4.56; - var roundedDouble = new RoundedDouble(2) - { - Value = otherValue - }; + var roundedDouble = new RoundedDouble(2, otherValue); // Precondition: Assert.IsTrue(otherValue.Equals(roundedDouble)); @@ -477,10 +409,7 @@ { // Setup double value = 1.234; - var roundedDouble = new RoundedDouble(4) - { - Value = value - }; + var roundedDouble = new RoundedDouble(4, value); // Precondition Assert.IsTrue(roundedDouble.Equals(value)); @@ -499,10 +428,7 @@ { // Setup double value = 1.234; - var roundedDouble = new RoundedDouble(4) - { - Value = 3.21543 - }; + var roundedDouble = new RoundedDouble(4, 3.21543); // Precondition Assert.IsFalse(roundedDouble.Equals(value)); @@ -521,10 +447,7 @@ { // Setup double value = 1.234; - var roundedDouble = new RoundedDouble(4) - { - Value = value - }; + var roundedDouble = new RoundedDouble(4, value); // Precondition Assert.IsTrue(roundedDouble.Equals(value)); @@ -543,10 +466,7 @@ { // Setup double value = 1.234; - var roundedDouble = new RoundedDouble(4) - { - Value = 3.21543 - }; + var roundedDouble = new RoundedDouble(4, 3.21543); // Precondition Assert.IsFalse(roundedDouble.Equals(value)); @@ -564,10 +484,7 @@ public void ImplicitConversion_FromRoundedDoubleToDouble_ConvertedValueIsEqual() { // Setup - var roundedDouble = new RoundedDouble(4) - { - Value = 3.2154 - }; + var roundedDouble = new RoundedDouble(4, 3.2154); // Call double convertedValue = roundedDouble; @@ -589,5 +506,23 @@ Assert.AreEqual(doubleValue, roundedDoubleValue.Value); Assert.AreEqual(15, roundedDoubleValue.NumberOfDecimalPlaces); } + + [Test] + [TestCase(0, 1d)] + [TestCase(2, 1.24)] + [TestCase(3, 1.236)] + [TestCase(15, 1.236000000000000)] + public void ToPrecision_VariousScenarios_ReturnRoundedDouble(int newPrecision, double expectedValue) + { + // Setup + var original = new RoundedDouble(3, 1.236); + + // Call + RoundedDouble convertedResult = original.ToPrecision(newPrecision); + + // Assert + Assert.AreEqual(newPrecision, convertedResult.NumberOfDecimalPlaces); + Assert.AreEqual(expectedValue, convertedResult.Value); + } } } \ No newline at end of file Index: Demo/Ringtoets/src/Demo.Ringtoets/Commands/AddNewDemoDikeAssessmentSectionCommand.cs =================================================================== diff -u -ra887863a3992744a394591e17072811eb9478ebc -raf38c7a9724254095e2e3a631dd7e974465a1fb9 --- Demo/Ringtoets/src/Demo.Ringtoets/Commands/AddNewDemoDikeAssessmentSectionCommand.cs (.../AddNewDemoDikeAssessmentSectionCommand.cs) (revision a887863a3992744a394591e17072811eb9478ebc) +++ Demo/Ringtoets/src/Demo.Ringtoets/Commands/AddNewDemoDikeAssessmentSectionCommand.cs (.../AddNewDemoDikeAssessmentSectionCommand.cs) (revision af38c7a9724254095e2e3a631dd7e974465a1fb9) @@ -1,5 +1,6 @@ -using System; -using System.Linq; +using System.Linq; + +using Core.Common.Base.Data; using Core.Common.Controls.Commands; using Core.Common.Gui; using Ringtoets.Common.Forms.PresentationObjects; @@ -117,7 +118,7 @@ calculation.InputParameters.SetSurfaceLine(pipingFailureMechanism.SurfaceLines.First(sl => sl.Name == "PK001_0001")); calculation.InputParameters.SoilProfile = pipingFailureMechanism.SoilProfiles.First(sl => sl.Name == "AD640M00_Segment_36005_1D2"); calculation.InputParameters.PhreaticLevelExit.Mean = 3; - calculation.InputParameters.AssessmentLevel.Value = 0.0; + calculation.InputParameters.AssessmentLevel = (RoundedDouble)0.0; calculation.InputParameters.ThicknessCoverageLayer = new LognormalDistribution(); calculation.InputParameters.ThicknessAquiferLayer = new LognormalDistribution(); } Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/PipingInput.cs =================================================================== diff -u -ra5b051a25a6bb059d5928e29a8d741a8ec31fcd5 -raf38c7a9724254095e2e3a631dd7e974465a1fb9 --- Ringtoets/Piping/src/Ringtoets.Piping.Data/PipingInput.cs (.../PipingInput.cs) (revision a5b051a25a6bb059d5928e29a8d741a8ec31fcd5) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/PipingInput.cs (.../PipingInput.cs) (revision af38c7a9724254095e2e3a631dd7e974465a1fb9) @@ -38,9 +38,9 @@ { private const double seepageLengthStandardDeviationFraction = 0.1; private readonly GeneralPipingInput generalInputParameters; - private readonly RoundedDouble assessmentLevel; - private readonly RoundedDouble exitPointL; - private readonly RoundedDouble entryPointL; + private RoundedDouble assessmentLevel; + private RoundedDouble exitPointL; + private RoundedDouble entryPointL; /// /// Initializes a new instance of the class. @@ -99,7 +99,7 @@ } set { - assessmentLevel.Value = value; + assessmentLevel = value.ToPrecision(assessmentLevel.NumberOfDecimalPlaces); } } @@ -122,7 +122,7 @@ { throw new ArgumentOutOfRangeException("value", Resources.PipingInput_EntryPointL_Value_must_be_greater_than_or_equal_to_zero); } - entryPointL.Value = value; + entryPointL = value.ToPrecision(entryPointL.NumberOfDecimalPlaces); UpdateSeepageLength(); } } @@ -146,7 +146,7 @@ { throw new ArgumentOutOfRangeException("value", Resources.PipingInput_ExitPointL_Value_must_be_greater_than_zero); } - exitPointL.Value = value; + exitPointL = value.ToPrecision(exitPointL.NumberOfDecimalPlaces); UpdateSeepageLength(); } } Index: Ringtoets/Piping/src/Ringtoets.Piping.Forms/PropertyClasses/PipingInputContextProperties.cs =================================================================== diff -u -ra5b051a25a6bb059d5928e29a8d741a8ec31fcd5 -raf38c7a9724254095e2e3a631dd7e974465a1fb9 --- Ringtoets/Piping/src/Ringtoets.Piping.Forms/PropertyClasses/PipingInputContextProperties.cs (.../PipingInputContextProperties.cs) (revision a5b051a25a6bb059d5928e29a8d741a8ec31fcd5) +++ Ringtoets/Piping/src/Ringtoets.Piping.Forms/PropertyClasses/PipingInputContextProperties.cs (.../PipingInputContextProperties.cs) (revision af38c7a9724254095e2e3a631dd7e974465a1fb9) @@ -203,7 +203,7 @@ throw new ArgumentException(message); } - data.WrappedData.AssessmentLevel.Value = value.DesignWaterLevel; + data.WrappedData.AssessmentLevel = (RoundedDouble)value.DesignWaterLevel; data.WrappedData.HydraulicBoundaryLocation = value; data.WrappedData.NotifyObservers(); } Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/PipingInputTest.cs =================================================================== diff -u -ra5b051a25a6bb059d5928e29a8d741a8ec31fcd5 -raf38c7a9724254095e2e3a631dd7e974465a1fb9 --- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/PipingInputTest.cs (.../PipingInputTest.cs) (revision a5b051a25a6bb059d5928e29a8d741a8ec31fcd5) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/PipingInputTest.cs (.../PipingInputTest.cs) (revision af38c7a9724254095e2e3a631dd7e974465a1fb9) @@ -92,6 +92,22 @@ } [Test] + public void ExitPointL_SetToValueWithTooManyDecimalPlaces_ValueIsRounded() + { + // Setup + var pipingInput = new PipingInput(new GeneralPipingInput()); + + int originalNumberOfDecimalPlaces = pipingInput.ExitPointL.NumberOfDecimalPlaces; + + // Call + pipingInput.ExitPointL = new RoundedDouble(5, 1.23456); + + // Assert + Assert.AreEqual(originalNumberOfDecimalPlaces, pipingInput.ExitPointL.NumberOfDecimalPlaces); + Assert.AreEqual(1.23, pipingInput.ExitPointL.Value); + } + + [Test] [TestCase(0)] [TestCase(-1e-6)] [TestCase(-21)] @@ -123,6 +139,22 @@ } [Test] + public void EntryPointL_SetToNewValueWithTooManyDecimalPlaces_ValueIsRounded() + { + // Setup + var pipingInput = new PipingInput(new GeneralPipingInput()); + + int originalNumberOfDecimalPlaces = pipingInput.EntryPointL.NumberOfDecimalPlaces; + + // Call + pipingInput.EntryPointL = new RoundedDouble(5, 9.87654); + + // Assert + Assert.AreEqual(originalNumberOfDecimalPlaces, pipingInput.EntryPointL.NumberOfDecimalPlaces); + Assert.AreEqual(9.88, pipingInput.EntryPointL.Value); + } + + [Test] [TestCase(double.NaN, double.NaN, double.NaN)] [TestCase(double.NaN, 3, double.NaN)] [TestCase(2, double.NaN, double.NaN)] @@ -158,5 +190,21 @@ // Assert Assert.IsNaN(pipingInput.SeepageLength.Mean); } + + [Test] + public void AssessmentLevel_SetToNewValueWithTooManyDecimalPlaces_ValueIsRounded() + { + // Setup + var pipingInput = new PipingInput(new GeneralPipingInput()); + + int originalNumberOfDecimalPlaces = pipingInput.AssessmentLevel.NumberOfDecimalPlaces; + + // Call + pipingInput.AssessmentLevel = new RoundedDouble(5, -8.29292); + + // Assert + Assert.AreEqual(originalNumberOfDecimalPlaces, pipingInput.AssessmentLevel.NumberOfDecimalPlaces); + Assert.AreEqual(-8.29, pipingInput.AssessmentLevel.Value); + } } } \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/PropertyClasses/PipingInputContextPropertiesTest.cs =================================================================== diff -u -ra5b051a25a6bb059d5928e29a8d741a8ec31fcd5 -raf38c7a9724254095e2e3a631dd7e974465a1fb9 --- Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/PropertyClasses/PipingInputContextPropertiesTest.cs (.../PipingInputContextPropertiesTest.cs) (revision a5b051a25a6bb059d5928e29a8d741a8ec31fcd5) +++ Ringtoets/Piping/test/Ringtoets.Piping.Forms.Test/PropertyClasses/PipingInputContextPropertiesTest.cs (.../PipingInputContextPropertiesTest.cs) (revision af38c7a9724254095e2e3a631dd7e974465a1fb9) @@ -361,10 +361,7 @@ double assessmentLevel = new Random(21).NextDouble(); var inputParameters = new PipingInput(new GeneralPipingInput()) { - AssessmentLevel = - { - Value = assessmentLevel - } + AssessmentLevel = (RoundedDouble)assessmentLevel }; inputParameters.Attach(projectObserver);