示例#1
0
        static void TestLimitedIntegerRange(BigInteger value, BitWidthAndSignPair signAndBitwidth)
        {
            var ltdInt = LimitedIntegerType.CreateLimitedIntegerType(value, null);

            ltdInt.Value.Should().Be(value);
            ltdInt.IsSigned.Should().Be(signAndBitwidth.IsSigned);
            ltdInt.BitWidth.Should().Be(signAndBitwidth.BitWidth);
        }
        static BigInteger Normalise(BigInteger value, BitWidthAndSignPair signAndBitwidth, IConfiguration configuration)
        {
            var minAndMax = MinAndMaxMap.Instance[signAndBitwidth];
            var oldValue  = value;

            value &= minAndMax.Mask;

            var state = (configuration?.State as CalcState) ?? new CalcState();

            if (oldValue != value)
            {
                if (configuration?.AllowOverOrUnderflow ?? true)
                {
                    state.OverOrUnderflowOccurred = true;
                }
                else
                {
                    throw new InvalidCalcOperationException("Overflow or underflow of LimitedIntegerTypes is not permitted.");
                }
            }

            if (signAndBitwidth.IsSigned)
            {
                if (value > minAndMax.Max)
                {
                    value -= (minAndMax.Mask + 1);
                }
            }

            if ((oldValue >= 0) != (value >= 0))
            {
                if (configuration?.AllowSignChange ?? true)
                {
                    state.SignChangedOccurred = true;
                }
                else
                {
                    throw new InvalidCalcOperationException("Sign change through overflow or underflow of LimitedIntegerTypes is not permitted.");
                }
            }

            return(value);
        }
示例#3
0
        private LimitedIntegerToken(BigInteger typedValue, IntegerBitWidth bitWidth, bool isSigned, bool isNeg, string rawToken, SourcePosition position, IConfiguration configuration)
            : base(LiteralTokenType.LimitedInteger, (isNeg ? typedValue * -1 : typedValue), rawToken, position)
        {
            if (isNeg)
            {
                typedValue *= -1;
            }
            SignAndBitWidth = new BitWidthAndSignPair(bitWidth, isSigned);
            _minAndMax      = MinAndMaxMap.Instance[SignAndBitWidth];

            if (!(configuration?.IgnoreLimitedIntegerMaxMinRange ?? false))
            {
                if (typedValue < _minAndMax.Min)
                {
                    throw new ParseException($"{typedValue} is less than the minimum of {_minAndMax.Min} for a {bitWidth.GetEnumDescription()}-bit {(isSigned ? "signed" : "unsigned")} {nameof(LimitedIntegerToken)} ");
                }
                else if (typedValue > _minAndMax.Max)
                {
                    throw new ParseException($"{typedValue} is greater than the maximum of {_minAndMax.Max} for a {bitWidth.GetEnumDescription()}-bit {(isSigned ? "signed" : "unsigned")} {nameof(LimitedIntegerToken)} ");
                }
            }
        }
 public LimitedIntegerType(BigInteger value, BitWidthAndSignPair signAndBitwidth, IConfiguration configuration)
     : base(Normalise(value, signAndBitwidth, configuration), DataType.LimitedInteger)
 {
     SignAndBitWidth = signAndBitwidth;
     _minAndMax      = MinAndMaxMap.Instance[SignAndBitWidth];
 }