diff --git a/src/TopDownProteomics/Chemistry/ChemicalFormula.cs b/src/TopDownProteomics/Chemistry/ChemicalFormula.cs index c46f4c7..d7de743 100644 --- a/src/TopDownProteomics/Chemistry/ChemicalFormula.cs +++ b/src/TopDownProteomics/Chemistry/ChemicalFormula.cs @@ -314,6 +314,8 @@ private ChemicalFormula Merge(ChemicalFormula otherFormula, bool add) for (int i = 0; i < newCommonElements.Length; i++) newCommonElements[i] = -otherCommonElements[i]; + + formula._commonElements = newCommonElements; } formula._commonElementEntities = otherFormula._commonElementEntities; @@ -380,7 +382,8 @@ private ChemicalFormula Merge(ChemicalFormula otherFormula, bool add) /// public ChemicalFormula Multiply(int multiplier) { - if (multiplier == 0) + // If either side is '0' just return Empty + if (this == Empty || multiplier == 0) return Empty; if (multiplier == 1) @@ -413,6 +416,32 @@ public ChemicalFormula Multiply(int multiplier) return formula; } + #region Operator Overloads + /// Implements the operator +. + /// The c1. + /// The c2. + public static ChemicalFormula operator +(ChemicalFormula c1, ChemicalFormula c2) => c1.Merge(c2, true); + + /// Implements the operator -. + /// The c1. + /// The c2. + public static ChemicalFormula operator -(ChemicalFormula c1, ChemicalFormula c2) => c1.Merge(c2, false); + + /// Implements the operator - (negation). + /// The c1. + public static ChemicalFormula operator -(ChemicalFormula c1) => c1.Multiply(-1); + + /// Implements the operator *. + /// The c1. + /// The multiplier. + public static ChemicalFormula operator *(ChemicalFormula c1, int multiplier) => c1.Multiply(multiplier); + + /// Implements the operator *. + /// The multiplier. + /// The c1. + public static ChemicalFormula operator *(int multiplier, ChemicalFormula c1) => c1.Multiply(multiplier); + #endregion + /// Parses the string into a chemical formula. /// The formula. /// The element provider. diff --git a/tests/TopDownProteomics.Tests/Chemistry/ChemicalFormulaTest.cs b/tests/TopDownProteomics.Tests/Chemistry/ChemicalFormulaTest.cs index 0aabab1..0609d20 100644 --- a/tests/TopDownProteomics.Tests/Chemistry/ChemicalFormulaTest.cs +++ b/tests/TopDownProteomics.Tests/Chemistry/ChemicalFormulaTest.cs @@ -419,6 +419,49 @@ public void SubtractTest() }); } + [Test] + public void WorkingWithEmptyTest() + { + var a = ChemicalFormula.Empty; + var b = ChemicalFormula.ParseString("CH2".AsSpan(), _elementProvider); + + var diff = a.Add(b); + + this.SimpleParseTest(diff, new[] + { + Tuple.Create("C", 1), + Tuple.Create("H", 2), + }); + + diff = a.Subtract(b); + + this.SimpleParseTest(diff, new[] + { + Tuple.Create("C", -1), + Tuple.Create("H", -2), + }); + + diff = a.Multiply(12); + + Assert.AreEqual(ChemicalFormula.Empty, diff); + } + + [Test] + public void OperatorOverloadsTest() + { + var a = ChemicalFormula.ParseString("C2H4".AsSpan(), _elementProvider); + var b = ChemicalFormula.ParseString("CH2".AsSpan(), _elementProvider); + + this.SimpleParseTest(a + b, new[] { Tuple.Create("C", 3), Tuple.Create("H", 6), }); + this.SimpleParseTest(a - b, new[] { Tuple.Create("C", 1), Tuple.Create("H", 2), }); + this.SimpleParseTest(a * 3, new[] { Tuple.Create("C", 6), Tuple.Create("H", 12), }); + this.SimpleParseTest(3 * a, new[] { Tuple.Create("C", 6), Tuple.Create("H", 12), }); + this.SimpleParseTest(-a, new[] { Tuple.Create("C", -2), Tuple.Create("H", -4), }); + + Assert.IsFalse(a == b); + Assert.IsTrue(a != b); + } + [Test] public void HashCodeTest() {