diff --git a/VectoCore/Utils/SI.cs b/VectoCore/Utils/SI.cs
index d4a895ac313bd4b6a0cfbead80d22b1581dab1dd..49adfc1d02e1b4ed0850f5ad3ed207fd1207e92d 100644
--- a/VectoCore/Utils/SI.cs
+++ b/VectoCore/Utils/SI.cs
@@ -1,5 +1,4 @@
 using System;
-using System.CodeDom;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
@@ -8,12 +7,14 @@ using System.Globalization;
 using System.Linq;
 using System.Runtime.CompilerServices;
 using System.Runtime.Serialization;
-using System.Text;
 using Newtonsoft.Json;
 using TUGraz.VectoCore.Exceptions;
 
 namespace TUGraz.VectoCore.Utils
 {
+	/// <summary>
+	/// Special SI Class for Scalar Values. Converts implicitely to double.
+	/// </summary>
 	public class Scalar : SIBase<Scalar>
 	{
 		static Scalar()
@@ -28,9 +29,34 @@ namespace TUGraz.VectoCore.Utils
 			return self.Val;
 		}
 
-		public static implicit operator Scalar(double val)
+		public static Scalar operator +(Scalar si1, Scalar si2)
+		{
+			return new Scalar(si1.Val + si2.Val);
+		}
+
+		public static Scalar operator +(Scalar si1, double si2)
+		{
+			return new Scalar(si1.Val + si2);
+		}
+
+		public static Scalar operator +(double si1, Scalar si2)
+		{
+			return new Scalar(si1 + si2.Val);
+		}
+
+		public static Scalar operator -(Scalar si1, Scalar si2)
 		{
-			return new Scalar(val);
+			return new Scalar(si1.Val - si2.Val);
+		}
+
+		public static Scalar operator -(Scalar si1, double si2)
+		{
+			return new Scalar(si1.Val - si2);
+		}
+
+		public static Scalar operator -(double si1, Scalar si2)
+		{
+			return new Scalar(si1 - si2.Val);
 		}
 	}
 
@@ -94,27 +120,26 @@ namespace TUGraz.VectoCore.Utils
 		protected Meter(double val) : base(new SI(val).Meter) {}
 	}
 
-	public class Ton : SIBase<Ton>
+	public class Kilogram : SIBase<Kilogram>
 	{
-		static Ton()
+		static Kilogram()
 		{
-			Constructors.Add(typeof(Ton), val => new Ton(val));
+			Constructors.Add(typeof(Kilogram), val => new Kilogram(val));
 		}
 
 		[JsonConstructor]
-		protected Ton(double val) : base(new SI(val).Ton) {}
+		protected Kilogram(double val) : base(new SI(val).Kilo.Gramm) {}
 	}
 
-
-	public class Kilogram : SIBase<Kilogram>
+	public class Ton : SIBase<Ton>
 	{
-		static Kilogram()
+		static Ton()
 		{
-			Constructors.Add(typeof(Kilogram), val => new Kilogram(val));
+			Constructors.Add(typeof(Ton), val => new Ton(val));
 		}
 
 		[JsonConstructor]
-		protected Kilogram(double val) : base(new SI(val).Kilo.Gramm) {}
+		protected Ton(double val) : base(new SI(val).Ton) {}
 	}
 
 	public class SquareMeter : SIBase<SquareMeter>
@@ -265,11 +290,6 @@ namespace TUGraz.VectoCore.Utils
 			return Constructors[typeof(T)](val);
 		}
 
-		protected SIBase(Type type, Func<double, T> constructor)
-		{
-			Constructors[type] = constructor;
-		}
-
 		protected SIBase(SI si) : base(si) {}
 
 		#region Operators
@@ -286,33 +306,22 @@ namespace TUGraz.VectoCore.Utils
 
 		public static T operator +(SI si1, SIBase<T> si2)
 		{
-			return si2 + si1;
-		}
-
-		public static T operator +(SIBase<T> si1, double d)
-		{
-			return ((si1 as SI) + d).Cast<T>();
-		}
-
-		public static T operator +(double d, SIBase<T> si)
-		{
-			return si + d;
+			return (si1 + (si2 as SI)).Cast<T>();
 		}
 
-
 		public static T operator -(SIBase<T> si1)
 		{
-			return 0 - si1;
+			return (-(si1 as SI)).Cast<T>();
 		}
 
 		public static T operator -(SIBase<T> si1, SIBase<T> si2)
 		{
-			return (si1 as SI) - si2;
+			return ((si1 as SI) - (si2 as SI)).Cast<T>();
 		}
 
 		public static T operator -(SIBase<T> si1, SI si2)
 		{
-			return (-1 * si2) + si1;
+			return ((si1 as SI) - si2).Cast<T>();
 		}
 
 		public static T operator -(SI si1, SIBase<T> si2)
@@ -320,19 +329,9 @@ namespace TUGraz.VectoCore.Utils
 			return (si1 - (si2 as SI)).Cast<T>();
 		}
 
-		public static T operator -(SIBase<T> si, double d)
-		{
-			return ((si as SI) - d).Cast<T>();
-		}
-
-		public static T operator -(double d, SIBase<T> si)
-		{
-			return (d - (si as SI)).Cast<T>();
-		}
-
 		public static T operator *(double d, SIBase<T> si)
 		{
-			return si * d;
+			return (d * (si as SI)).Cast<T>();
 		}
 
 		public static T operator *(SIBase<T> si, double d)
@@ -340,11 +339,6 @@ namespace TUGraz.VectoCore.Utils
 			return ((si as SI) * d).Cast<T>();
 		}
 
-		public static T operator /(double d, SIBase<T> si)
-		{
-			return si / d;
-		}
-
 		public static T operator /(SIBase<T> si, double d)
 		{
 			return ((si as SI) / d).Cast<T>();
@@ -519,14 +513,16 @@ namespace TUGraz.VectoCore.Utils
 		{
 			var numerator = new List<Unit>();
 			var denominator = new List<Unit>();
-			Numerator.ToList().ForEach(unit => ConvertToBasicUnits(unit, numerator, denominator));
-			Denominator.ToList().ForEach(unit => ConvertToBasicUnits(unit, denominator, numerator));
-			return new SI(Val, numerator, denominator);
+			var numeratorFactor = 1.0;
+			Numerator.ToList().ForEach(unit => ConvertToBasicUnits(unit, numerator, denominator, ref numeratorFactor));
+			var denominatorFactor = 1.0;
+			Denominator.ToList().ForEach(unit => ConvertToBasicUnits(unit, denominator, numerator, ref denominatorFactor));
+			return new SI(Val * numeratorFactor / denominatorFactor, numerator, denominator);
 		}
 
 
 		private static void ConvertToBasicUnits(Unit unit, ICollection<Unit> numerator,
-			ICollection<Unit> denominator)
+			ICollection<Unit> denominator, ref double factor)
 		{
 			switch (unit) {
 				case Unit.W:
@@ -546,7 +542,7 @@ namespace TUGraz.VectoCore.Utils
 					denominator.Add(Unit.s);
 					break;
 				case Unit.t:
-					numerator.Add(Unit.k);
+					factor *= 1000;
 					numerator.Add(Unit.k);
 					numerator.Add(Unit.g);
 					break;
@@ -583,11 +579,31 @@ namespace TUGraz.VectoCore.Utils
 		public SI Sqrt()
 		{
 			var si = ToBasicUnits();
-			var numerator = si.Numerator.Where((u, i) => i % 2 == 0);
-			var denominator = si.Denominator.Where((u, i) => i % 2 == 0);
-			var root = new SI(Math.Sqrt(si.Val), numerator, denominator);
-			Contract.Requires(root * root == this);
-			return root;
+			if (si.Numerator.Length % 2 != 0 || si.Denominator.Length % 2 != 0) {
+				throw new VectoException(
+					string.Format("The squareroot cannot be calculated because the Unit-Exponents are not even: [{0}]",
+						si.GetUnitString()));
+			}
+
+			var numerator = new List<Unit>();
+			var currentNumerator = si.Numerator.ToList();
+			while (currentNumerator.Count != 0) {
+				var unit = currentNumerator.First();
+				currentNumerator.Remove(unit);
+				currentNumerator.Remove(unit);
+				numerator.Add(unit);
+			}
+
+			var denominator = new List<Unit>();
+			var currentDenominator = si.Denominator.ToList();
+			while (currentDenominator.Count != 0) {
+				var unit = currentDenominator.First();
+				currentDenominator.Remove(unit);
+				currentDenominator.Remove(unit);
+				denominator.Add(unit);
+			}
+
+			return new SI(Math.Sqrt(si.Val), numerator, denominator);
 		}
 
 		#region Unit Definitions
@@ -765,57 +781,25 @@ namespace TUGraz.VectoCore.Utils
 			Contract.Requires(si2 != null);
 			if (!si1.HasEqualUnit(si2)) {
 				throw new VectoException(
-					string.Format("Operator '-' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
+					string.Format("Operator '-' can only operate on SI Objects with the same unit. Got: {0} - {1}", si1, si2));
 			}
 			return new SI(si1.Val - si2.Val, si1.Numerator, si1.Denominator);
 		}
 
-		public static SI operator *(SI si1, SI si2)
-		{
-			Contract.Requires(si1 != null);
-			Contract.Requires(si2 != null);
-			var numerator = si1.Numerator.Concat(si2.Numerator);
-			var denominator = si1.Denominator.Concat(si2.Denominator);
-			return new SI(si1.Val * si2.Val, numerator, denominator);
-		}
-
-		public static SI operator /(SI si1, SI si2)
-		{
-			Contract.Requires(si1 != null);
-			Contract.Requires(si2 != null);
-			var numerator = si1.Numerator.Concat(si2.Denominator);
-			var denominator = si1.Denominator.Concat(si2.Numerator);
-			return new SI(si1.Val / si2.Val, numerator, denominator);
-		}
-
-		public static SI operator +(SI si1, double d)
-		{
-			Contract.Requires(si1 != null);
-			return new SI(si1.Val + d, si1);
-		}
-
-		public static SI operator +(double d, SI si1)
+		public static SI operator -(SI si1)
 		{
 			Contract.Requires(si1 != null);
-			return si1 + d;
+			return new SI(-si1.Val, si1);
 		}
 
-		public static SI operator -(SI si1, double d)
-		{
-			Contract.Requires(si1 != null);
-			return new SI(si1.Val - d, si1);
-		}
 
-		public static SI operator -(double d, SI si1)
-		{
-			Contract.Requires(si1 != null);
-			return new SI(d - si1.Val, si1);
-		}
-
-		public static SI operator -(SI si1)
+		public static SI operator *(SI si1, SI si2)
 		{
 			Contract.Requires(si1 != null);
-			return 0 - si1;
+			Contract.Requires(si2 != null);
+			var numerator = si1.Numerator.Concat(si2.Numerator);
+			var denominator = si1.Denominator.Concat(si2.Denominator);
+			return new SI(si1.Val * si2.Val, numerator, denominator);
 		}
 
 		public static SI operator *(SI si1, double d)
@@ -830,6 +814,15 @@ namespace TUGraz.VectoCore.Utils
 			return new SI(d * si1.Val, si1);
 		}
 
+		public static SI operator /(SI si1, SI si2)
+		{
+			Contract.Requires(si1 != null);
+			Contract.Requires(si2 != null);
+			var numerator = si1.Numerator.Concat(si2.Denominator);
+			var denominator = si1.Denominator.Concat(si2.Numerator);
+			return new SI(si1.Val / si2.Val, numerator, denominator);
+		}
+
 		public static SI operator /(SI si1, double d)
 		{
 			Contract.Requires(si1 != null);
@@ -839,7 +832,7 @@ namespace TUGraz.VectoCore.Utils
 		public static SI operator /(double d, SI si1)
 		{
 			Contract.Requires(si1 != null);
-			return new SI(d / si1.Val, si1);
+			return new SI(d / si1.Val, si1.Denominator, si1.Numerator);
 		}
 
 		public static bool operator <(SI si1, SI si2)
@@ -848,54 +841,55 @@ namespace TUGraz.VectoCore.Utils
 			Contract.Requires(si2 != null);
 			if (!si1.HasEqualUnit(si2)) {
 				throw new VectoException(
-					string.Format("Operator '<' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
+					string.Format("Operator '<' can only operate on SI Objects with the same unit. Got: {0} < {1}", si1, si2));
 			}
 			return si1.Val < si2.Val;
 		}
 
+		public static bool operator <(SI si1, double d)
+		{
+			Contract.Requires(si1 != null);
+			return si1 != null && si1.Val < d;
+		}
+
 		public static bool operator >(SI si1, SI si2)
 		{
 			Contract.Requires(si1 != null);
 			Contract.Requires(si2 != null);
 			if (!si1.HasEqualUnit(si2)) {
 				throw new VectoException(
-					string.Format("Operator '>' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
+					string.Format("Operator '>' can only operate on SI Objects with the same unit. Got: {0} > {1}", si1, si2));
 			}
 			return si1.Val > si2.Val;
 		}
 
-		public static bool operator <=(SI si1, SI si2)
+		public static bool operator >(SI si1, double d)
 		{
 			Contract.Requires(si1 != null);
-			Contract.Requires(si2 != null);
-			if (!si1.HasEqualUnit(si2)) {
-				throw new VectoException(
-					string.Format("Operator '<=' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
-			}
-			return si1.Val <= si2.Val;
+			return si1 != null && si1.Val > d;
 		}
 
-		public static bool operator >=(SI si1, SI si2)
+		public static bool operator >(double d, SI si1)
 		{
 			Contract.Requires(si1 != null);
-			Contract.Requires(si2 != null);
-			if (!si1.HasEqualUnit(si2)) {
-				throw new VectoException(
-					string.Format("Operator '>=' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
-			}
-			return si1.Val >= si2.Val;
+			return si1 != null && d > si1.Val;
 		}
 
-		public static bool operator <(SI si1, double d)
+		public static bool operator <(double d, SI si1)
 		{
 			Contract.Requires(si1 != null);
-			return si1 != null && si1.Val < d;
+			return si1 != null && d < si1.Val;
 		}
 
-		public static bool operator >(SI si1, double d)
+		public static bool operator <=(SI si1, SI si2)
 		{
 			Contract.Requires(si1 != null);
-			return si1 != null && si1.Val > d;
+			Contract.Requires(si2 != null);
+			if (!si1.HasEqualUnit(si2)) {
+				throw new VectoException(
+					string.Format("Operator '<=' can only operate on SI Objects with the same unit. Got: {0} <= {1}", si1, si2));
+			}
+			return si1.Val <= si2.Val;
 		}
 
 		public static bool operator <=(SI si1, double d)
@@ -904,34 +898,21 @@ namespace TUGraz.VectoCore.Utils
 			return si1 != null && si1.Val <= d;
 		}
 
-		public static bool operator >=(SI si1, double d)
+		public static bool operator >=(SI si1, SI si2)
 		{
 			Contract.Requires(si1 != null);
-			return si1 != null && si1.Val >= d;
-		}
-
-		#endregion
-
-		#region Double Conversion
-
-		/// <summary>
-		///     Casts an SI Unit to an double.
-		/// </summary>
-		/// <param name="si"></param>
-		/// <returns></returns>
-		public static explicit operator double(SI si)
-		{
-			return si.Val;
+			Contract.Requires(si2 != null);
+			if (!si1.HasEqualUnit(si2)) {
+				throw new VectoException(
+					string.Format("Operator '>=' can only operate on SI Objects with the same unit. Got: {0} >= {1}", si1, si2));
+			}
+			return si1.Val >= si2.Val;
 		}
 
-		/// <summary>
-		///     Casts a double to an SI Unit.
-		/// </summary>
-		/// <param name="d"></param>
-		/// <returns></returns>
-		public static explicit operator SI(double d)
+		public static bool operator >=(SI si1, double d)
 		{
-			return new SI(d);
+			Contract.Requires(si1 != null);
+			return si1 != null && si1.Val >= d;
 		}
 
 		#endregion
@@ -1057,16 +1038,6 @@ namespace TUGraz.VectoCore.Utils
 
 		#endregion
 
-		public Scalar Scalar()
-		{
-			var si = ToBasicUnits();
-			if (si.Numerator.Length == 0 && si.Denominator.Length == 0) {
-				return Val.SI<Scalar>();
-			}
-			throw new InvalidCastException("The SI Unit is not a scalar.");
-		}
-
-
 		public virtual string ToOutputFormat(uint? decimals = null, double? outputFactor = null, bool? showUnit = null)
 		{
 			decimals = decimals ?? 4;
diff --git a/VectoCoreTest/Utils/AssertHelper.cs b/VectoCoreTest/Utils/AssertHelper.cs
index 079d3ef0cc9ea08b604cd988c6f1d8971a395f6f..7897625df34802348c7717ab294795c1da4ca83f 100644
--- a/VectoCoreTest/Utils/AssertHelper.cs
+++ b/VectoCoreTest/Utils/AssertHelper.cs
@@ -17,12 +17,12 @@ namespace TUGraz.VectoCore.Tests.Utils
 				Assert.Fail("Expected Exception {0}, but no exception occured.", typeof(T));
 			} catch (T ex) {
 				if (!string.IsNullOrEmpty(message)) {
-					Assert.AreEqual(message, ex.Message,
-						string.Format("Expected Exception message: {0}, but got message: {1}", message, ex.Message));
+					Assert.AreEqual(message, ex.Message);
 				}
 			}
 		}
 
+		[DebuggerHidden]
 		public static void AreRelativeEqual(SI expected, SI actual)
 		{
 			Assert.IsTrue(actual.HasEqualUnit(expected),
@@ -48,13 +48,13 @@ namespace TUGraz.VectoCore.Tests.Utils
 
 			if (expected.IsEqual(0.0)) {
 				Assert.AreEqual(expected, actual, DoubleExtensionMethods.Tolerance,
-					string.Format("Actual value is different. Difference: {3} Expected: {0}, Actual: {1}, Tolerance: {2}{4}",
+					string.Format("Actual value is different. Expected: {0}, Actual: {1}, Difference: {3}, ToleranceFactor: {2}{4}",
 						expected, actual, toleranceFactor, expected - actual, message));
 				return;
 			}
 
 			Assert.IsTrue(Math.Abs(actual / expected - 1) < toleranceFactor,
-				string.Format("Actual value is different. Difference: {3} Expected: {0}, Actual: {1}, Tolerance: {2}{4}",
+				string.Format("Actual value is different. Expected: {0}, Actual: {1}, Difference: {3}, ToleranceFactor: {2}{4}",
 					expected, actual, toleranceFactor, expected - actual, message));
 		}
 	}
diff --git a/VectoCoreTest/Utils/SITest.cs b/VectoCoreTest/Utils/SITest.cs
index a98b038e5dd93421815689b553bd311e1251daf1..cfd1224efaaf88708d15f5f5f1b6de3d3ba47592 100644
--- a/VectoCoreTest/Utils/SITest.cs
+++ b/VectoCoreTest/Utils/SITest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Diagnostics.CodeAnalysis;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using TUGraz.VectoCore.Exceptions;
 using TUGraz.VectoCore.Utils;
@@ -9,24 +8,6 @@ namespace TUGraz.VectoCore.Tests.Utils
 	[TestClass]
 	public class SITest
 	{
-		/// <summary>
-		/// Assert an expected Exception.
-		/// </summary>
-		/// <typeparam name="T"></typeparam>
-		/// <param name="func"></param>
-		/// <param name="message"></param>
-		public static void AssertException<T>(Action func, string message = null) where T : Exception
-		{
-			try {
-				func();
-				Assert.Fail("Expected Exception {0}, but no exception occured.", typeof(T));
-			} catch (T ex) {
-				if (message != null) {
-					Assert.AreEqual(message, ex.Message);
-				}
-			}
-		}
-
 		[TestMethod]
 		public void SI_TypicalUsageTest()
 		{
@@ -62,7 +43,7 @@ namespace TUGraz.VectoCore.Tests.Utils
 			var angVeloSum = angularVelocity + angularVelocity2;
 			Assert.IsInstanceOfType(angVeloSum, typeof(PerSecond));
 			Assert.AreEqual((400.0 + 600) / 60 * 2 * Math.PI, angVeloSum.Value(), 0.0000001);
-			AssertException<VectoException>(() => { var x = 500.SI().Watt + 300.SI().Newton; });
+			AssertHelper.Exception<VectoException>(() => { var x = 500.SI().Watt + 300.SI().Newton; });
 
 			//subtract
 			var angVeloDiff = angularVelocity - angularVelocity2;
@@ -92,11 +73,11 @@ namespace TUGraz.VectoCore.Tests.Utils
 
 
 			// ConvertTo only allows conversion if the units are correct.
-			AssertException<VectoException>(() => { var x = 40.SI<Newton>().ConvertTo().Watt; });
+			AssertHelper.Exception<VectoException>(() => { var x = 40.SI<Newton>().ConvertTo().Watt; });
 			var res1 = 40.SI<Newton>().ConvertTo().Newton;
 
 			// Cast only allows the cast if the units are correct.
-			AssertException<VectoException>(() => { var x = 40.SI().Newton.Cast<Watt>(); });
+			AssertHelper.Exception<VectoException>(() => { var x = 40.SI().Newton.Cast<Watt>(); });
 			var res2 = 40.SI().Newton.Cast<Newton>();
 		}
 
@@ -156,21 +137,55 @@ namespace TUGraz.VectoCore.Tests.Utils
 		}
 
 		[TestMethod]
-		public void SI_Test_Addition_Subtraction()
+		public void SI_Comparison_Operators()
 		{
 			var v1 = 600.SI<NewtonMeter>();
 			var v2 = 455.SI<NewtonMeter>();
+			var v3 = 600.SI<NewtonMeter>();
+			var v4 = 100.SI<Watt>();
+			var d = 700;
 
 			Assert.IsTrue(v1 > v2);
-			Assert.IsTrue(v2 < v1);
-			Assert.IsTrue(v1 >= v2);
-			Assert.IsTrue(v2 <= v1);
-
 			Assert.IsFalse(v1 < v2);
+			AssertHelper.Exception<VectoException>(() => { var x = v1 < v4; },
+				"Operator '<' can only operate on SI Objects with the same unit. Got: 600.0000 [Nm] < 100.0000 [W]");
+			AssertHelper.Exception<VectoException>(() => { var x = v1 > v4; },
+				"Operator '>' can only operate on SI Objects with the same unit. Got: 600.0000 [Nm] > 100.0000 [W]");
+			AssertHelper.Exception<VectoException>(() => { var x = v1 <= v4; },
+				"Operator '<=' can only operate on SI Objects with the same unit. Got: 600.0000 [Nm] <= 100.0000 [W]");
+			AssertHelper.Exception<VectoException>(() => { var x = v1 >= v4; },
+				"Operator '>=' can only operate on SI Objects with the same unit. Got: 600.0000 [Nm] >= 100.0000 [W]");
+
+			SI si = null;
+			Assert.IsFalse(si > 3);
+			Assert.IsFalse(si < 3);
+			Assert.IsFalse(si >= 3);
+			Assert.IsFalse(si <= 3);
+
+			Assert.IsFalse(3 > si);
+			Assert.IsFalse(3 < si);
+			Assert.IsFalse(si >= 3);
+			Assert.IsFalse(si <= 3);
+
+
+			Assert.IsTrue(v2 < v1);
 			Assert.IsFalse(v2 > v1);
+
+			Assert.IsTrue(v1 >= v2);
 			Assert.IsFalse(v1 <= v2);
+
+			Assert.IsTrue(v2 <= v1);
 			Assert.IsFalse(v2 >= v1);
 
+			Assert.IsTrue(v1 <= v3);
+			Assert.IsTrue(v1 >= v3);
+
+			Assert.IsTrue(v1 < d);
+			Assert.IsFalse(v1 > d);
+			Assert.IsFalse(v1 >= d);
+			Assert.IsTrue(v1 <= d);
+
+
 			Assert.AreEqual(1, new SI().CompareTo(null));
 			Assert.AreEqual(1, new SI().CompareTo("not an SI"));
 			Assert.AreEqual(-1, new SI().Meter.CompareTo(new SI().Kilo.Meter.Per.Hour));
@@ -179,43 +194,184 @@ namespace TUGraz.VectoCore.Tests.Utils
 			Assert.AreEqual(0, 1.SI().CompareTo(1.SI()));
 			Assert.AreEqual(-1, 1.SI().CompareTo(2.SI()));
 			Assert.AreEqual(1, 2.SI().CompareTo(1.SI()));
+		}
+
+
+		[TestMethod]
+		public void SI_Test_Addition_Subtraction()
+		{
+			AssertHelper.AreRelativeEqual(3.SI(), 1.SI() + 2.SI());
+			AssertHelper.AreRelativeEqual(-1.SI(), 1.SI() - 2.SI());
+
+			AssertHelper.AreRelativeEqual(3.SI<Scalar>(), 1.SI<Scalar>() + 2.SI<Scalar>());
+			AssertHelper.AreRelativeEqual(3.SI<Scalar>(), 1 + 2.SI<Scalar>());
+			AssertHelper.AreRelativeEqual(3.SI<Scalar>(), 1.SI<Scalar>() + 2);
+			AssertHelper.AreRelativeEqual(-1.SI<Scalar>(), 1.SI<Scalar>() - 2.SI<Scalar>());
+			AssertHelper.AreRelativeEqual(-1.SI<Scalar>(), 1 - 2.SI<Scalar>());
+			AssertHelper.AreRelativeEqual(-1.SI<Scalar>(), 1.SI<Scalar>() - 2);
+
+			AssertHelper.AreRelativeEqual(3.SI<NewtonMeter>(), 1.SI<NewtonMeter>() + 2.SI<NewtonMeter>());
+			AssertHelper.AreRelativeEqual(-1.SI<NewtonMeter>(), 1.SI<NewtonMeter>() - 2.SI<NewtonMeter>());
+
+			AssertHelper.AreRelativeEqual(3.SI<NewtonMeter>(), 1.SI().Newton.Meter + 2.SI<NewtonMeter>());
+			AssertHelper.AreRelativeEqual(-1.SI<NewtonMeter>(), 1.SI().Newton.Meter - 2.SI<NewtonMeter>());
+
+			AssertHelper.AreRelativeEqual(3.SI<NewtonMeter>(), 1.SI<NewtonMeter>() + 2.SI().Newton.Meter);
+			AssertHelper.AreRelativeEqual(-1.SI<NewtonMeter>(), 1.SI<NewtonMeter>() - 2.SI().Newton.Meter);
+
+			AssertHelper.Exception<VectoException>(() => { var x = 1.SI().Second - 1.SI<Meter>(); },
+				"Operator '-' can only operate on SI Objects with the same unit. Got: 1.0000 [s] - 1.0000 [m]");
+		}
+
+		[TestMethod]
+		public void SI_SpecialUnits()
+		{
+			Scalar scalar = 3.SI<Scalar>();
+			AssertHelper.AreRelativeEqual(3.SI(), scalar);
+			double scalarDouble = scalar;
+			AssertHelper.AreRelativeEqual(3, scalarDouble);
+
+			MeterPerSecond meterPerSecond = 2.SI<MeterPerSecond>();
+			AssertHelper.AreRelativeEqual(2.SI().Meter.Per.Second, meterPerSecond);
+
+			Second second = 1.SI<Second>();
+			AssertHelper.AreRelativeEqual(1.SI().Second, second);
+
+			Watt watt = 2.SI<Watt>();
+			AssertHelper.AreRelativeEqual(2.SI().Watt, watt);
 
+			PerSecond perSecond = 1.SI<PerSecond>();
+			AssertHelper.AreRelativeEqual(1.SI().Per.Second, perSecond);
 
-			NewtonMeter v3 = v1 + v2;
+			RoundsPerMinute rpm = 20.SI<RoundsPerMinute>();
+			AssertHelper.AreRelativeEqual(20.SI().Rounds.Per.Minute, rpm);
+			AssertHelper.AreRelativeEqual(20.RPMtoRad(), rpm);
+			AssertHelper.AreRelativeEqual(2.0943951023931953, rpm.Value());
 
-			NewtonMeter v4 = v1 - v2;
+			Radian radian = 30.SI<Radian>();
+			AssertHelper.AreRelativeEqual(30.SI().Radian, radian);
+			AssertHelper.AreRelativeEqual(30, radian.Value());
 
-			var v5 = v1 * v2;
-			Assert.IsTrue(v5.HasEqualUnit(0.SI().Square.Newton.Meter));
-			Assert.AreEqual(v1.Value() * v2.Value(), v5.Value());
+			Newton newton = 3.SI<Newton>();
+			AssertHelper.AreRelativeEqual(3.SI().Newton, newton);
 
-			var v6 = v1 / v2;
-			Assert.IsTrue(v6.HasEqualUnit(0.SI()));
-			Assert.AreEqual(v1.Value() / v2.Value(), v6.Value());
+			NewtonMeter newtonMeter = 5.SI<NewtonMeter>();
+			AssertHelper.AreRelativeEqual(5.SI().Newton.Meter, newtonMeter);
+			AssertHelper.AreRelativeEqual(5.SI().Meter.Newton, newtonMeter);
 
-			var t = 10.SI<NewtonMeter>();
-			var angVelo = 5.SI<PerSecond>();
+			MeterPerSquareSecond meterPerSquareSecond = 3.SI<MeterPerSquareSecond>();
+			AssertHelper.AreRelativeEqual(3.SI().Meter.Per.Square.Second, meterPerSquareSecond);
 
-			Watt w = t * angVelo;
-			Watt w1 = angVelo * t;
+			Kilogram kilogram = 3.SI<Kilogram>();
+			AssertHelper.AreRelativeEqual(3.SI().Kilo.Gramm, kilogram);
+			AssertHelper.AreRelativeEqual(3, kilogram.Value());
 
-			NewtonMeter t1 = w / angVelo;
+			Ton ton = 5.SI<Ton>();
+			AssertHelper.AreRelativeEqual(5.SI().Ton, ton);
+			AssertHelper.AreRelativeEqual(5000.SI<Kilogram>(), ton);
 
-			PerSecond angVelo1 = w / t;
-			Second sec = t / w;
+			SquareMeter squareMeter = 3.SI<SquareMeter>();
+			AssertHelper.AreRelativeEqual(3.SI().Square.Meter, squareMeter);
+
+			CubicMeter cubicMeter = 3.SI<CubicMeter>();
+			AssertHelper.AreRelativeEqual(3.SI().Cubic.Meter, cubicMeter);
+
+			KilogramSquareMeter kilogramSquareMeter = 3.SI<KilogramSquareMeter>();
+			AssertHelper.AreRelativeEqual(3.SI().Kilo.Gramm.Square.Meter, kilogramSquareMeter);
+
+			KilogramPerWattSecond kilogramPerWattSecond = 3.SI<KilogramPerWattSecond>();
+			AssertHelper.AreRelativeEqual(3.SI().Kilo.Gramm.Per.Watt.Second, kilogramPerWattSecond);
 		}
 
+		/// <summary>
+		/// VECTO-111
+		/// </summary>
 		[TestMethod]
-		public void SI_SpecialUnits()
+		public void SI_ReziprokDivision()
+		{
+			var test = 2.0.SI<Second>();
+
+			var actual = 1.0 / test;
+			var expected = 0.5.SI<PerSecond>();
+
+			AssertHelper.AreRelativeEqual(expected, actual);
+		}
+
+		[TestMethod]
+		public void SI_Multiplication_Division()
 		{
-			2.SI<MeterPerSecond>();
-			1.SI<Second>();
-			2.SI<Watt>();
-			1.SI<PerSecond>();
-			2.SI<RoundsPerMinute>();
-			3.SI<Newton>();
-			4.SI<Radian>();
-			5.SI<NewtonMeter>();
+			AssertHelper.AreRelativeEqual(12.SI(), 3.SI() * 4.SI());
+			AssertHelper.AreRelativeEqual(12.SI(), 3 * 4.SI());
+			AssertHelper.AreRelativeEqual(12.SI(), 3.SI() * 4);
+
+			AssertHelper.AreRelativeEqual(12.SI<NewtonMeter>(), 3.SI<Newton>() * 4.SI<Meter>());
+			AssertHelper.AreRelativeEqual(12.SI<NewtonMeter>(), 3 * 4.SI<NewtonMeter>());
+			AssertHelper.AreRelativeEqual(12.SI<NewtonMeter>(), 3.SI<NewtonMeter>() * 4);
+			AssertHelper.AreRelativeEqual(12.SI().Square.Newton.Meter, 3.SI<NewtonMeter>() * 4.SI<NewtonMeter>());
+
+			AssertHelper.AreRelativeEqual(3.SI(), 12.SI() / 4);
+			AssertHelper.AreRelativeEqual(3.SI(), 12.SI() / 4.SI());
+			AssertHelper.AreRelativeEqual(3.SI(), 12.SI<NewtonMeter>() / 4.SI<NewtonMeter>());
+			AssertHelper.AreRelativeEqual(3.SI<Scalar>(), 12.SI<NewtonMeter>() / 4.SI<NewtonMeter>());
+
+			AssertHelper.AreRelativeEqual(3.SI<NewtonMeter>(), 12.SI<NewtonMeter>() / 4);
+			AssertHelper.AreRelativeEqual(3.SI().Per.Newton.Meter, 12 / 4.SI<NewtonMeter>());
+
+
+			var newtonMeter = 10.SI<NewtonMeter>();
+			var perSecond = 5.SI<PerSecond>();
+			var watt = (10 * 5).SI<Watt>();
+			var second = (1.0 / 5.0).SI<Second>();
+
+			AssertHelper.AreRelativeEqual(watt, newtonMeter * perSecond);
+			AssertHelper.AreRelativeEqual(watt, perSecond * newtonMeter);
+
+			AssertHelper.AreRelativeEqual(newtonMeter, watt / perSecond);
+			AssertHelper.AreRelativeEqual(perSecond, watt / newtonMeter);
+
+			AssertHelper.AreRelativeEqual(second, newtonMeter / watt);
+		}
+
+		[TestMethod]
+		public void SI_MeterPerSecond_Div_Meter()
+		{
+			PerSecond actual = 6.SI<MeterPerSecond>() / 2.SI<Meter>();
+			AssertHelper.AreRelativeEqual(3.SI().Per.Second, actual);
+		}
+
+		[TestMethod]
+		public void SI_SimplifyUnits()
+		{
+			AssertHelper.AreRelativeEqual(3.SI(), 18.SI().Kilo.Gramm / 6.SI().Kilo.Gramm);
+			AssertHelper.AreRelativeEqual(3.SI(), 18.SI<NewtonMeter>() / 6.SI<NewtonMeter>());
+
+			AssertHelper.AreRelativeEqual(18.SI(), 3.SI().Kilo.Gramm * 6.SI().Per.Kilo.Gramm);
+			AssertHelper.AreRelativeEqual(18.SI<Meter>(), 3.SI().Kilo.Gramm.Meter * 6.SI().Per.Kilo.Gramm);
+
+
+			AssertHelper.AreRelativeEqual(3.SI().Kilo.Gramm.Square.Meter.Per.Cubic.Second, 3.SI<Watt>());
+			AssertHelper.AreRelativeEqual(3.SI().Kilo.Gramm.Meter.Per.Square.Second, 3.SI<Newton>());
+			AssertHelper.AreRelativeEqual(3000.SI().Kilo.Gramm, 3.SI<Ton>());
+			AssertHelper.AreRelativeEqual(3.SI().Kilo.Kilo.Gramm.ConvertTo().Ton, 3.SI<Ton>().ConvertTo().Ton);
+
+			AssertHelper.AreRelativeEqual(3.SI<Meter>(), 3000.SI().Milli.Meter);
+
+			AssertHelper.AreRelativeEqual(36.SI().Square.Newton.Meter, 6.SI<NewtonMeter>() * 6.SI<NewtonMeter>());
+			AssertHelper.AreRelativeEqual(36.SI().Newton.Newton.Meter.Meter, 6.SI<NewtonMeter>() * 6.SI<NewtonMeter>());
+		}
+
+		[TestMethod]
+		public void SI_Math()
+		{
+			AssertHelper.AreRelativeEqual(-3, -3.SI().Value());
+			AssertHelper.AreRelativeEqual(3.SI(), (-3).SI().Abs());
+
+			AssertHelper.AreRelativeEqual(6.SI(), 36.SI().Sqrt());
+			AssertHelper.AreRelativeEqual(6.SI<NewtonMeter>(), (6.SI<NewtonMeter>() * 6.SI<NewtonMeter>()).Sqrt());
+			AssertHelper.AreRelativeEqual(6.SI().Second, 36.SI().Square.Second.Sqrt());
+
+			AssertHelper.Exception<VectoException>(() => 36.SI().Second.Sqrt(),
+				"The squareroot cannot be calculated because the Unit-Exponents are not even: [s]");
 		}
 	}
 }
\ No newline at end of file