/// <summary> /// Splits the range on the given <paramref name="splitPoint"/>. /// </summary> /// <param name="splitPoint">The point on the range to split it.</param> /// <param name="includeSplitPointToUpperRange">Which range gets the <paramref name="splitPoint"/>?</param> /// <param name="whatToDoWithResults">What to do with the result?</param> /// <returns>Result <see cref="IRangeMathableSingleSize{SByte, BigInteger}"/>s.</returns> public IRangeMathableSingleSize <SByte, BigInteger>[] Split(SByte splitPoint, bool includeSplitPointToUpperRange, RangeMathematicResultUseage whatToDoWithResults) { IRangeMathableSingleSize <SByte, BigInteger>[] result; if (TheRange.EmptyRange) { result = new IRangeMathableSingleSize <SByte, BigInteger>[2] { default(SByteRangeMathable), default(SByteRangeMathable) }; } else { result = new IRangeMathableSingleSize <SByte, BigInteger> [2]; switch (TheRange.CompareTo(splitPoint)) { case -1: result[0] = new SByteRangeMathable(TheRange.EmptyRange, TheRange.StartBound, TheRange.EndBound); result[1] = default(SByteRangeMathable); break; case 0: if (includeSplitPointToUpperRange) { if (TheRange.StartBound == TheRange.EndBound || TheRange.StartBound == splitPoint) { result[0] = default(SByteRangeMathable); result[1] = new SByteRangeMathable(TheRange.EmptyRange, TheRange.StartBound, TheRange.EndBound); } else { result[0] = new SByteRangeMathable(TheRange.EmptyRange, TheRange.StartBound, (SByte)(splitPoint - 1)); result[1] = new SByteRangeMathable(TheRange.EmptyRange, splitPoint, TheRange.EndBound); } } else { if (TheRange.StartBound == TheRange.EndBound || TheRange.EndBound == splitPoint) { result[0] = new SByteRangeMathable(TheRange.EmptyRange, TheRange.StartBound, TheRange.EndBound); result[1] = default(SByteRangeMathable); } else { result[0] = new SByteRangeMathable(TheRange.EmptyRange, TheRange.StartBound, splitPoint); result[1] = new SByteRangeMathable(TheRange.EmptyRange, (SByte)(splitPoint + 1), TheRange.EndBound); } } break; case 1: result[0] = default(SByteRangeMathable); result[1] = new SByteRangeMathable(TheRange.EmptyRange, TheRange.StartBound, TheRange.EndBound); break; } } // working with the result to do the wanted actions if ((whatToDoWithResults & RangeMathematicResultUseage.UseLowestResultRangeOnOwnRange) > 0) { if (result[0].StartBound > TheRange.EndBound) { TheRange.EndBound = result[0].EndBound; TheRange.StartBound = result[0].StartBound; } else { TheRange.StartBound = result[0].StartBound; TheRange.EndBound = result[0].EndBound; } TheRange.EmptyRange = result[0].EmptyRange; } else if ((whatToDoWithResults & RangeMathematicResultUseage.UseHighestResultRangeOnOwnRange) > 0) { if (result[1].StartBound > TheRange.EndBound) { TheRange.EndBound = result[1].EndBound; TheRange.StartBound = result[1].StartBound; } else { TheRange.StartBound = result[1].StartBound; TheRange.EndBound = result[1].EndBound; } TheRange.EmptyRange = result[1].EmptyRange; } return(result); }
/// <summary> /// Splits the range in nearly equal sized ranges. /// </summary> /// <param name="includeOddToUpperRange">If the range range is odd where to add the element on the split to?</param> /// <param name="whatToDoWithResults">What to do with the result?</param> /// <returns>Result <see cref="IRangeMathable{SByte, BigInteger}"/>s.</returns> public IRangeMathableSingleSize <SByte, BigInteger>[] Split(bool includeOddToUpperRange, RangeMathematicResultUseage whatToDoWithResults) { IRangeMathableSingleSize <SByte, BigInteger>[] result = new IRangeMathableSingleSize <SByte, BigInteger> [2]; Int32 tempSize = BigInteger.ToInt32(RangeSize()); switch (tempSize.CompareTo(1)) { case -1: result[0] = default(SByteRangeMathable); result[1] = default(SByteRangeMathable); break; case 0: if (includeOddToUpperRange) { result[0] = default(SByteRangeMathable); result[1] = new SByteRangeMathable(true, TheRange.StartBound, TheRange.EndBound); } else { result[0] = new SByteRangeMathable(true, TheRange.StartBound, TheRange.EndBound); result[1] = default(SByteRangeMathable); } break; case 1: bool storedOddBit = (tempSize & 1) == 1; Int32 halfSize = tempSize >> 1; if (storedOddBit) { if (halfSize > 0) { if (includeOddToUpperRange) { result[0] = new SByteRangeMathable(false, TheRange.StartBound, (SByte)(TheRange.StartBound + halfSize - 1)); result[1] = new SByteRangeMathable(false, (SByte)(TheRange.EndBound - halfSize), TheRange.EndBound); } else { result[0] = new SByteRangeMathable(false, TheRange.StartBound, (SByte)(TheRange.StartBound + halfSize)); result[1] = new SByteRangeMathable(false, (SByte)(TheRange.EndBound - halfSize + 1), TheRange.EndBound); } } else { if (includeOddToUpperRange) { result[0] = default(SByteRangeMathable); result[1] = new SByteRangeMathable(false, TheRange.EndBound, TheRange.EndBound); } else { result[0] = new SByteRangeMathable(false, TheRange.StartBound, TheRange.StartBound); result[1] = default(SByteRangeMathable); } } } else { if (halfSize > 0) { result[0] = new SByteRangeMathable(false, TheRange.StartBound, (SByte)(TheRange.StartBound + halfSize - 1)); result[1] = new SByteRangeMathable(false, (SByte)(TheRange.EndBound - halfSize + 1), TheRange.EndBound); } else { result[0] = default(SByteRangeMathable); result[1] = default(SByteRangeMathable); } } break; } // working with the result to do the wanted actions if ((whatToDoWithResults & RangeMathematicResultUseage.UseLowestResultRangeOnOwnRange) > 0) { if (result[0].StartBound > TheRange.EndBound) { TheRange.EndBound = result[0].EndBound; TheRange.StartBound = result[0].StartBound; } else { TheRange.StartBound = result[0].StartBound; TheRange.EndBound = result[0].EndBound; } TheRange.EmptyRange = result[0].EmptyRange; } else if ((whatToDoWithResults & RangeMathematicResultUseage.UseHighestResultRangeOnOwnRange) > 0) { if (result[1].StartBound > TheRange.EndBound) { TheRange.EndBound = result[1].EndBound; TheRange.StartBound = result[1].StartBound; } else { TheRange.StartBound = result[1].StartBound; TheRange.EndBound = result[1].EndBound; } TheRange.EmptyRange = result[1].EmptyRange; } return(result); }
/// <summary> /// Combines this range with the given range <paramref name="toCombine"/> based on the given <see cref="RangeCombination"/>. /// </summary> /// <param name="toCombine">The other range to combine with.</param> /// <param name="combinationType">How to combine the 2 ranges.</param> /// <param name="whatToDoWithResults">What to do with the result?</param> /// <returns>Result <see cref="IRangeMathable{SByte, SByte}"/>s.</returns> /// <exception cref="ArgumentOutOfRangeException">The <paramref name="combinationType"/> is not a valid <see cref="RangeCombination"/> value!</exception> public IRangeMathableSingleSize <SByte, BigInteger>[] Combine(IRangeMathableSingleSize <SByte, BigInteger> toCombine, RangeCombination combinationType, RangeMathematicResultUseage whatToDoWithResults) { IRangeMathableSingleSize <SByte, BigInteger>[] result; if (toCombine == null) { result = new IRangeMathableSingleSize <SByte, BigInteger> [1]; switch (combinationType) { case RangeCombination.Difference: case RangeCombination.Union: result[0] = new SByteRangeMathable(TheRange.EmptyRange, TheRange.StartBound, TheRange.EndBound); break; case RangeCombination.Intersect: result[0] = default(SByteRangeMathable); break; default: throw new ArgumentOutOfRangeException("The combinationType is not a valid RangeCombinations value!"); } } else { int comparationResult = CompareTo(toCombine); switch (combinationType) { case RangeCombination.Difference: if (TheRange.EmptyRange) { result = new IRangeMathableSingleSize <SByte, BigInteger>[1] { new SByteRangeMathable(toCombine.EmptyRange, toCombine.StartBound, toCombine.EndBound) }; } else if (toCombine.EmptyRange) { result = new IRangeMathableSingleSize <SByte, BigInteger>[1] { new SByteRangeMathable(TheRange.EmptyRange, TheRange.StartBound, TheRange.EndBound) }; } else { if (comparationResult == 0) { result = new IRangeMathableSingleSize <SByte, BigInteger>[1] { new SByteRangeMathable(true, 0, 0) }; } else { if (TheRange.EndBound < toCombine.EndBound) { result = new IRangeMathableSingleSize <SByte, BigInteger> [2]; Int32 tempNewBound = toCombine.StartBound - 1; if (tempNewBound <= TheRange.StartBound) { result[0] = new SByteRangeMathable(true, TheRange.StartBound, TheRange.StartBound); } else { result[0] = new SByteRangeMathable(false, TheRange.StartBound, (SByte)tempNewBound); } tempNewBound = TheRange.EndBound + 1; if (tempNewBound >= toCombine.EndBound) { result[1] = new SByteRangeMathable(true, toCombine.EndBound, toCombine.EndBound); } else { result[1] = new SByteRangeMathable(false, (SByte)tempNewBound, toCombine.EndBound); } } else { Int32 newEndBound = toCombine.StartBound - 1; if (newEndBound <= TheRange.StartBound) { result = new IRangeMathableSingleSize <SByte, BigInteger>[1] { new SByteRangeMathable(true, TheRange.StartBound, TheRange.StartBound) }; } else { result = new IRangeMathableSingleSize <SByte, BigInteger>[1] { new SByteRangeMathable(false, TheRange.StartBound, (SByte)newEndBound) }; } } } } break; case RangeCombination.Intersect: result = new IRangeMathableSingleSize <SByte, BigInteger> [1]; if (TheRange.EmptyRange || toCombine.EmptyRange) { result[0] = default(SByteRangeMathable); } else { switch (comparationResult) { case -1: if (toCombine.StartBound > SByte.MinValue && TheRange.EndBound < (toCombine.StartBound - 1)) { result[0] = default(SByteRangeMathable); } else { if (TheRange.EndBound > toCombine.EndBound) { result[0] = new SByteRangeMathable(false, toCombine.StartBound, toCombine.EndBound); } else { result[0] = new SByteRangeMathable(false, toCombine.StartBound, TheRange.EndBound); } } break; case 0: result[0] = new SByteRangeMathable(false, TheRange.StartBound, TheRange.EndBound); break; case 1: if (TheRange.StartBound < SByte.MinValue && toCombine.EndBound < (TheRange.StartBound - 1)) { result[0] = default(SByteRangeMathable); } else { if (toCombine.EndBound > TheRange.EndBound) { result[0] = new SByteRangeMathable(false, toCombine.StartBound, toCombine.EndBound); } else { result[0] = new SByteRangeMathable(false, toCombine.StartBound, TheRange.EndBound); } } break; } } break; case RangeCombination.Union: if (TheRange.EmptyRange && toCombine.EmptyRange) { result = new IRangeMathableSingleSize <SByte, BigInteger>[1] { default(SByteRangeMathable) }; } else { switch (comparationResult) { case -1: if (TheRange.EmptyRange) { result = new IRangeMathableSingleSize <SByte, BigInteger>[1] { new SByteRangeMathable(toCombine.EmptyRange, toCombine.StartBound, toCombine.EndBound) }; } else if (toCombine.EmptyRange) { result = new IRangeMathableSingleSize <SByte, BigInteger>[1] { new SByteRangeMathable(TheRange.EmptyRange, TheRange.StartBound, TheRange.EndBound) }; } else { if (TheRange.EndBound < SByte.MaxValue && (TheRange.EndBound + 1) < toCombine.StartBound) { result = new IRangeMathableSingleSize <SByte, BigInteger> [2]; result[0] = new SByteRangeMathable(false, TheRange.StartBound, TheRange.EndBound); result[1] = new SByteRangeMathable(false, toCombine.StartBound, toCombine.EndBound); } else { result = new IRangeMathableSingleSize <SByte, BigInteger> [1]; if (TheRange.EndBound <= toCombine.EndBound) { result[0] = new SByteRangeMathable(false, TheRange.StartBound, toCombine.EndBound); } else { result[0] = new SByteRangeMathable(false, TheRange.StartBound, TheRange.EndBound); } } } break; case 0: result = new IRangeMathableSingleSize <SByte, BigInteger>[1] { new SByteRangeMathable(false, TheRange.StartBound, TheRange.EndBound) }; break; case 1: if (TheRange.EmptyRange) { result = new IRangeMathableSingleSize <SByte, BigInteger>[1] { new SByteRangeMathable(toCombine.EmptyRange, toCombine.StartBound, toCombine.EndBound) }; } else if (toCombine.EmptyRange) { result = new IRangeMathableSingleSize <SByte, BigInteger>[1] { new SByteRangeMathable(TheRange.EmptyRange, TheRange.StartBound, TheRange.EndBound) }; } else { if (toCombine.EndBound < SByte.MaxValue && TheRange.StartBound < (toCombine.EndBound + 1)) { result = new IRangeMathableSingleSize <SByte, BigInteger> [2]; result[1] = new SByteRangeMathable(false, toCombine.StartBound, toCombine.EndBound); result[0] = new SByteRangeMathable(false, TheRange.StartBound, TheRange.EndBound); } else { result = new IRangeMathableSingleSize <SByte, BigInteger> [1]; if (TheRange.EndBound >= toCombine.EndBound) { result[0] = new SByteRangeMathable(false, toCombine.StartBound, TheRange.EndBound); } else { result[0] = new SByteRangeMathable(false, toCombine.StartBound, toCombine.EndBound); } } } break; } } result = new IRangeMathableSingleSize <SByte, BigInteger>[1] { new SByteRangeMathable(TheRange.EmptyRange, TheRange.StartBound, TheRange.EndBound) }; break; default: throw new ArgumentOutOfRangeException("The combinationType is not a valid RangeCombinations value!"); } } // working with the result to do the wanted actions if ((whatToDoWithResults & RangeMathematicResultUseage.UseLowestResultRangeOnOwnRange) > 0) { if (result[0].StartBound > TheRange.EndBound) { TheRange.EndBound = result[0].EndBound; TheRange.StartBound = result[0].StartBound; } else { TheRange.StartBound = result[0].StartBound; TheRange.EndBound = result[0].EndBound; } TheRange.EmptyRange = result[0].EmptyRange; } else if ((whatToDoWithResults & RangeMathematicResultUseage.UseHighestResultRangeOnOwnRange) > 0) { int targetPosition = result.Length - 1; if (result[targetPosition].StartBound > TheRange.EndBound) { TheRange.EndBound = result[targetPosition].EndBound; TheRange.StartBound = result[targetPosition].StartBound; } else { TheRange.StartBound = result[targetPosition].StartBound; TheRange.EndBound = result[targetPosition].EndBound; } TheRange.EmptyRange = result[targetPosition].EmptyRange; } return(result); }