public void Utilities_NumberHelpers_CanConvertUIntToNormalizedFloatAndBack(uint value, uint minValue, uint maxValue, float expected)
    {
        var result = NumberHelpers.UIntToNormalizedFloat(value, minValue, maxValue);

        Assert.That(result, Is.EqualTo(expected).Within(float.Epsilon));

        var integer = NumberHelpers.NormalizedFloatToUInt(result, minValue, maxValue);

        Assert.That(integer, Is.EqualTo(Clamp(value, minValue, maxValue)));
    }
Beispiel #2
0
        ////REVIEW: This is some bad code duplication here between Read/WriteFloat&Double but given that there's no
        ////        way to use a type argument here, not sure how to get rid of it.

        public double ReadDouble(void *statePtr)
        {
            Debug.Assert(sizeInBits != 0);

            var valuePtr = (byte *)statePtr + (int)byteOffset;

            var fmt = (int)format;

            switch (fmt)
            {
            // If a control with an integer-based representation does not use the full range
            // of its integer size (e.g. only goes from [0..128]), processors or the parameters
            // above have to be used to re-process the resulting float values.
            case kFormatBit:
                if (sizeInBits == 1)
                {
                    return(MemoryHelpers.ReadSingleBit(valuePtr, bitOffset) ? 1.0f : 0.0f);
                }
                return(MemoryHelpers.ReadMultipleBitsAsNormalizedUInt(valuePtr, bitOffset, sizeInBits));

            case kFormatSBit:
                if (sizeInBits == 1)
                {
                    return(MemoryHelpers.ReadSingleBit(valuePtr, bitOffset) ? 1.0f : -1.0f);
                }
                return(MemoryHelpers.ReadMultipleBitsAsNormalizedUInt(valuePtr, bitOffset, sizeInBits) * 2.0f - 1.0f);

            case kFormatInt:
                Debug.Assert(sizeInBits == 32, "INT state must have sizeInBits=32");
                Debug.Assert(bitOffset == 0, "INT state must be byte-aligned");
                return(NumberHelpers.IntToNormalizedFloat(*(int *)valuePtr, int.MinValue, int.MaxValue) * 2.0f - 1.0f);

            case kFormatUInt:
                Debug.Assert(sizeInBits == 32, "UINT state must have sizeInBits=32");
                Debug.Assert(bitOffset == 0, "UINT state must be byte-aligned");
                return(NumberHelpers.UIntToNormalizedFloat(*(uint *)valuePtr, uint.MinValue, uint.MaxValue));

            case kFormatShort:
                Debug.Assert(sizeInBits == 16, "SHRT state must have sizeInBits=16");
                Debug.Assert(bitOffset == 0, "SHRT state must be byte-aligned");
                return(NumberHelpers.IntToNormalizedFloat(*(short *)valuePtr, short.MinValue, short.MaxValue) * 2.0f - 1.0f);

            case kFormatUShort:
                Debug.Assert(sizeInBits == 16, "USHT state must have sizeInBits=16");
                Debug.Assert(bitOffset == 0, "USHT state must be byte-aligned");
                return(NumberHelpers.UIntToNormalizedFloat(*(ushort *)valuePtr, ushort.MinValue, ushort.MaxValue));

            case kFormatByte:
                Debug.Assert(sizeInBits == 8, "BYTE state must have sizeInBits=8");
                Debug.Assert(bitOffset == 0, "BYTE state must be byte-aligned");
                return(NumberHelpers.UIntToNormalizedFloat(*valuePtr, byte.MinValue, byte.MaxValue));

            case kFormatSByte:
                Debug.Assert(sizeInBits == 8, "SBYT state must have sizeInBits=8");
                Debug.Assert(bitOffset == 0, "SBYT state must be byte-aligned");
                return(NumberHelpers.IntToNormalizedFloat(*(sbyte *)valuePtr, sbyte.MinValue, sbyte.MaxValue) * 2.0f - 1.0f);

            case kFormatFloat:
                Debug.Assert(sizeInBits == 32, "FLT state must have sizeInBits=32");
                Debug.Assert(bitOffset == 0, "FLT state must be byte-aligned");
                return(*(float *)valuePtr);

            case kFormatDouble:
                Debug.Assert(sizeInBits == 64, "DBL state must have sizeInBits=64");
                Debug.Assert(bitOffset == 0, "DBL state must be byte-aligned");
                return(*(double *)valuePtr);

            // Not supported:
            // - kFormatLong
            // - kFormatULong
            // - kFormatFloat
            // - kFormatDouble
            default:
                throw new Exception($"State format '{format}' is not supported as floating-point format");
            }
        }