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); }
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]; }