diff --git a/ICD.Common.Utils.Tests/Attributes/RangeAttributeTest.cs b/ICD.Common.Utils.Tests/Attributes/RangeAttributeTest.cs index edc7a3c..e777821 100644 --- a/ICD.Common.Utils.Tests/Attributes/RangeAttributeTest.cs +++ b/ICD.Common.Utils.Tests/Attributes/RangeAttributeTest.cs @@ -31,8 +31,8 @@ namespace ICD.Common.Utils.Tests.Attributes #region Remap To - [TestCase(0, 0)] - [TestCase(1.0, 1.0)] + [TestCase((double)0, (double)0)] + [TestCase((double)1, (double)1)] [TestCase(ushort.MaxValue, double.MaxValue)] [TestCase(short.MinValue, double.MinValue)] public void RemapToDoubleTest(object value, double expected) @@ -40,8 +40,7 @@ namespace ICD.Common.Utils.Tests.Attributes Assert.AreEqual(expected, RangeAttribute.RemapToDouble(value)); } - [TestCase(0, (ushort)0)] - [TestCase(1.0, (ushort)1)] + [TestCase((double)0, (ushort)32767)] [TestCase(double.MaxValue, ushort.MaxValue)] [TestCase(double.MinValue, ushort.MinValue)] public void RemapToUShortTest(object value, ushort expected) @@ -53,7 +52,7 @@ namespace ICD.Common.Utils.Tests.Attributes #region Remap From - [TestCase(0, typeof(ushort), (ushort)0)] + [TestCase((double)0, typeof(ushort), (ushort)32767)] [TestCase(double.MinValue, typeof(ushort), ushort.MinValue)] [TestCase(double.MaxValue, typeof(ushort), ushort.MaxValue)] public void RemapFromDoubleTest(double value, Type type, object expected) @@ -61,7 +60,7 @@ namespace ICD.Common.Utils.Tests.Attributes Assert.AreEqual(expected, RangeAttribute.RemapFromDouble(value, type)); } - [TestCase((ushort)0, typeof(double), 0)] + [TestCase((ushort)0, typeof(double), double.MinValue)] [TestCase(ushort.MinValue, typeof(double), double.MinValue)] [TestCase(ushort.MaxValue, typeof(double), double.MaxValue)] public void RemapFromUShortTest(ushort value, Type type, object expected) diff --git a/ICD.Common.Utils.Tests/MathUtilsTest.cs b/ICD.Common.Utils.Tests/MathUtilsTest.cs index 7591083..ebf3280 100644 --- a/ICD.Common.Utils.Tests/MathUtilsTest.cs +++ b/ICD.Common.Utils.Tests/MathUtilsTest.cs @@ -40,12 +40,6 @@ namespace ICD.Common.Utils.Tests Assert.AreEqual(100, MathUtils.MapRange(0, 10, 0, 100, 10)); } - [TestCase(double.MinValue, double.MaxValue, 0.0, 1.0, double.MaxValue, 1.0)] - public void MapRangeTest(double inputStart, double inputEnd, double outputStart, double outputEnd, double value, double expected) - { - Assert.AreEqual(expected, MathUtils.MapRange(inputStart, inputEnd, outputStart, outputEnd, value)); - } - [Test, UsedImplicitly] public void GetRangesTest() { diff --git a/ICD.Common.Utils/Attributes/RangeAttribute.cs b/ICD.Common.Utils/Attributes/RangeAttribute.cs index 8cef7fa..9590381 100644 --- a/ICD.Common.Utils/Attributes/RangeAttribute.cs +++ b/ICD.Common.Utils/Attributes/RangeAttribute.cs @@ -19,16 +19,21 @@ namespace ICD.Common.Utils.Attributes private static readonly Dictionary> s_RemapToDouble = new Dictionary> { + // Duh { typeof(double), o => (double)o}, - { typeof(ushort), o => MathUtils.MapRange(ushort.MinValue, ushort.MaxValue, double.MinValue, double.MaxValue, (double)o)}, - { typeof(short), o => MathUtils.MapRange(short.MinValue, short.MaxValue, double.MinValue, double.MaxValue, (double)o)}, - { typeof(uint), o => MathUtils.MapRange(uint.MinValue, uint.MaxValue, double.MinValue, double.MaxValue, (double)o)}, - { typeof(int), o => MathUtils.MapRange(int.MinValue, int.MaxValue, double.MinValue, double.MaxValue, (double)o)}, - { typeof(ulong), o => MathUtils.MapRange(ulong.MinValue, ulong.MaxValue, double.MinValue, double.MaxValue, (double)o)}, - { typeof(long), o => MathUtils.MapRange(long.MinValue, long.MaxValue, double.MinValue, double.MaxValue, (double)o)}, - { typeof(float), o => MathUtils.MapRange(float.MinValue, float.MaxValue, double.MinValue, double.MaxValue, (double)o)}, - { typeof(decimal), o => MathUtils.MapRange((double)decimal.MinValue, (double)decimal.MaxValue, double.MinValue, double.MaxValue, (double)o)}, - { typeof(byte), o => MathUtils.MapRange(byte.MinValue, byte.MaxValue, double.MinValue, double.MaxValue, (double)o)}, + + // Signed - Clamping prevents an overflow due to loss of precision + { typeof(short), o => MathUtils.Clamp(Convert.ToDouble(o) / short.MaxValue, -1, 1) * double.MaxValue}, + { typeof(int), o => MathUtils.Clamp(Convert.ToDouble(o) / int.MaxValue, -1, 1) * double.MaxValue}, + { typeof(long), o => MathUtils.Clamp(Convert.ToDouble(o) / long.MaxValue, -1, 1) * double.MaxValue}, + { typeof(float), o => MathUtils.Clamp(Convert.ToDouble(o) / float.MaxValue, -1, 1) * double.MaxValue}, + { typeof(decimal), o => MathUtils.Clamp(Convert.ToDouble(o) / (double)decimal.MaxValue, -1, 1) * double.MaxValue}, + + // Unsigned + { typeof(ushort), o => MathUtils.Clamp((Convert.ToDouble(o) / ushort.MaxValue - 0.5) * 2, -1, 1) * double.MaxValue}, + { typeof(uint), o => MathUtils.Clamp((Convert.ToDouble(o) / uint.MaxValue - 0.5) * 2, -1, 1) * double.MaxValue}, + { typeof(ulong), o => MathUtils.Clamp((Convert.ToDouble(o) / ulong.MaxValue - 0.5) * 2, -1, 1) * double.MaxValue}, + { typeof(byte), o => MathUtils.Clamp((Convert.ToDouble(o) / byte.MaxValue - 0.5) * 2, -1, 1) * double.MaxValue} }; /// @@ -37,16 +42,21 @@ namespace ICD.Common.Utils.Attributes private static readonly Dictionary> s_RemapFromDouble = new Dictionary> { - { typeof(double), v => v}, - { typeof(ushort), v => (ushort)(MathUtils.MapRange(double.MinValue, double.MaxValue, 0, 1, v) * ushort.MaxValue)}, - { typeof(short), v => (short)(MathUtils.MapRange(double.MinValue, double.MaxValue, -1, 1, v) * short.MaxValue)}, - { typeof(uint), v => (uint)(MathUtils.MapRange(double.MinValue, double.MaxValue, 0, 1, v) * uint.MaxValue)}, - { typeof(int), v =>(int)(MathUtils.MapRange(double.MinValue, double.MaxValue, -1, 1, v) * int.MaxValue)}, - { typeof(ulong), v => (ulong)(MathUtils.MapRange(double.MinValue, double.MaxValue, 0, 1, v) * ulong.MaxValue)}, - { typeof(long), v => (long)(MathUtils.MapRange(double.MinValue, double.MaxValue, -1, 1, v) * long.MaxValue)}, - { typeof(float), v => (float)(MathUtils.MapRange(double.MinValue, double.MaxValue, -1, 1, v) * float.MaxValue)}, - { typeof(decimal), v => (decimal)MathUtils.MapRange(double.MinValue, double.MaxValue, -1, 1, v) * decimal.MaxValue}, - { typeof(byte), v => (byte)(MathUtils.MapRange(double.MinValue, double.MaxValue, 0, 1, v) * byte.MaxValue)}, + // Duh + {typeof(double), v => v}, + + // Signed + {typeof(short), v => (short)(v / double.MaxValue * short.MaxValue)}, + {typeof(int), v => (int)(v / double.MaxValue * int.MaxValue)}, + {typeof(long), v => (long)(v / double.MaxValue * long.MaxValue)}, + {typeof(float), v => (float)(v / double.MaxValue * float.MaxValue)}, + {typeof(decimal), v => (decimal)(v / double.MaxValue) * decimal.MaxValue}, + + // Unsigned + {typeof(ushort), v => (ushort)((v / double.MaxValue + 1) / 2 * ushort.MaxValue)}, + {typeof(uint), v => (uint)((v / double.MaxValue + 1) / 2 * uint.MaxValue)}, + {typeof(ulong), v => (ulong)((v / double.MaxValue + 1) / 2 * ulong.MaxValue)}, + {typeof(byte), v => (byte)((v / double.MaxValue + 1) / 2 * byte.MaxValue)} }; private readonly object m_Min; @@ -231,7 +241,7 @@ namespace ICD.Common.Utils.Attributes /// public static ushort RemapToUShort(object value) { - return (ushort)(ushort.MaxValue * RemapToDouble(value)); + return (ushort)(ushort.MaxValue * (RemapToDouble(value) / double.MaxValue + 1) / 2); } #endregion