/// <summary> /// Gets the formatted number that this parser is able to extract. /// </summary> /// <param name="text">The source string.</param> public override FormattedNumber GetResult(string text) { Debug.Assert(LengthSuccessful > 0); if (LeadingZeroCount == Length && LeadingZeroCount > 0) { LeadingZeroCount--; } Debug.Assert(StartOffset + Length <= text.Length); string IntegerText = text.Substring(StartOffset + LeadingZeroCount, Length - LeadingZeroCount); string InvalidText = text.Substring(StartOffset + Length); CanonicalNumber Canonical; if (IntegerText == IntegerBase.Zero) { Canonical = CanonicalNumber.Zero; } else { Canonical = new CanonicalNumber(Sign, IntegerText); } return(new FormattedInteger(IntegerBase.Decimal, Sign, LeadingZeroCount, IntegerText, InvalidText, Canonical)); }
/// <summary> /// Gets the formatted number that this parser is able to extract. /// </summary> /// <param name="text">The source string.</param> public override FormattedNumber GetResult(string text) { Debug.Assert(LengthSuccessful > 0); if (LeadingZeroCount == Length && LeadingZeroCount > 0) { LeadingZeroCount--; } Debug.Assert(StartOffset + Length + Base.Suffix.Length <= text.Length); string IntegerText = text.Substring(StartOffset + LeadingZeroCount, Length - LeadingZeroCount); string InvalidText = text.Substring(StartOffset + Length + Base.Suffix.Length); CanonicalNumber Canonical; if (IntegerText == IntegerBase.Zero) { Canonical = CanonicalNumber.Zero; } else { // Convert to decimal. The result can start or finish with a zero string DecimalSignificand = IntegerBase.Convert(IntegerText, Base, IntegerBase.Decimal); Canonical = new CanonicalNumber(Sign, DecimalSignificand); } return(new FormattedInteger(Base, Sign, LeadingZeroCount, IntegerText, InvalidText, Canonical)); }
/// <summary> /// Returns the ratio of two numbers: x / y. /// </summary> /// <param name="x">The first number.</param> /// <param name="y">The second number.</param> public static FormattedNumber operator /(FormattedNumber x, FormattedNumber y) { CanonicalNumber OperationResult = x.Canonical / y.Canonical; FormattedNumber Result = FromCanonical(OperationResult); return(Result); }
/// <summary> /// Returns the negation of a number: -x. /// </summary> /// <param name="x">The number.</param> public static FormattedNumber operator -(FormattedNumber x) { CanonicalNumber OperationResult = -x.Canonical; FormattedNumber Result = FromCanonical(OperationResult); return(Result); }
/// <summary> /// Returns the square root of this object's value. /// </summary> public FormattedNumber Sqrt() { CanonicalNumber OperationResult = Canonical.Sqrt(); FormattedNumber Result = FromCanonical(OperationResult); return(Result); }
/// <summary> /// Returns this object's value divided by a specified power of two. /// </summary> /// <param name="x">The number.</param> public FormattedNumber ShiftRight(FormattedNumber x) { CanonicalNumber OperationResult = Canonical.ShiftRight(x.Canonical); FormattedNumber Result = FromCanonical(OperationResult); return(Result); }
/// <summary> /// Returns the bitwise XOR of this object's value and x. /// </summary> /// <param name="x">The number.</param> public FormattedNumber BitwiseXor(FormattedNumber x) { CanonicalNumber OperationResult = Canonical.BitwiseXor(x.Canonical); FormattedNumber Result = FromCanonical(OperationResult); return(Result); }
/// <summary> /// Returns the remainder when this object's value is divided by x. /// </summary> /// <param name="x">The divisor.</param> public FormattedNumber Remainder(FormattedNumber x) { CanonicalNumber OperationResult = Canonical.Remainder(x.Canonical); FormattedNumber Result = FromCanonical(OperationResult); return(Result); }
/// <summary> /// Returns this object's value divided by a specified power of two. /// </summary> /// <param name="other">The other number.</param> public CanonicalNumber ShiftRight(CanonicalNumber other) { if (other.TryParseInt(out int Shift)) { return(FromEFloat(NumberFloat >> Shift)); } else { return(NaN); } }
/// <summary> /// Gets the formatted number that this parser is able to extract. /// </summary> /// <param name="text">The source string.</param> public override FormattedNumber GetResult(string text) { Debug.Assert(LengthSuccessful > 0); if (LeadingZeroCount == IntegerLength && LeadingZeroCount > 0) { LeadingZeroCount--; } Debug.Assert(StartOffset + IntegerLength + 1 + FractionalLength <= text.Length); string IntegerText = text.Substring(StartOffset + LeadingZeroCount, IntegerLength - LeadingZeroCount); string FractionalText = text.Substring(StartOffset + IntegerLength + 1, FractionalLength); if (ExponentLength > 0) { string ExponentText; string InvalidText; string SignificandText; if (SeparatorCharacter != Parser.NoSeparator) { Debug.Assert(IntegerText.Length > 0 || FractionalText.Length > 0); ExponentText = text.Substring(StartOffset + IntegerLength + 1 + FractionalLength + 1 + ExponentStartOffset, ExponentLength); InvalidText = text.Substring(StartOffset + IntegerLength + 1 + FractionalLength + 1 + ExponentStartOffset + ExponentLength); SignificandText = GetSignificandText(IntegerText, FractionalText); } else { ExponentText = text.Substring(StartOffset + IntegerLength + 1 + ExponentStartOffset, ExponentLength); InvalidText = text.Substring(StartOffset + IntegerLength + 1 + ExponentStartOffset + ExponentLength); SignificandText = IntegerText; } CanonicalNumber Canonical = GetCanonical(Sign, SignificandText, ExponentSign, ExponentText); return(new FormattedReal(Sign, LeadingZeroCount, IntegerText, SeparatorCharacter, FractionalText, ExponentCharacter, ExponentSign, ExponentText, InvalidText, Canonical)); } else { string SignificandText = GetSignificandText(IntegerText, FractionalText); string InvalidText = text.Substring(StartOffset + IntegerLength + 1 + FractionalLength); CanonicalNumber Canonical = GetCanonical(Sign, SignificandText, OptionalSign.None, IntegerBase.Zero); return(new FormattedReal(Sign, LeadingZeroCount, IntegerText, SeparatorCharacter, FractionalText, Parser.NoSeparator, OptionalSign.None, string.Empty, InvalidText, Canonical)); } }
private CanonicalNumber GetCanonical(OptionalSign significandSign, string significandText, OptionalSign exponentSign, string exponentText) { CanonicalNumber Canonical; if (significandText == IntegerBase.Zero) { Canonical = CanonicalNumber.Zero; } else { Canonical = new CanonicalNumber(significandSign, significandText, exponentSign, exponentText); } return(Canonical); }
/// <summary> /// Initializes a new instance of the <see cref="CanonicalNumber"/> class. /// </summary> /// <param name="f">An EFloat.</param> public static CanonicalNumber FromEFloat(Number f) { if (f.IsNaN) { return(NaN); } if (f.IsPositiveInfinity) { return(PositiveInfinity); } if (f.IsNegativeInfinity) { return(NegativeInfinity); } Debug.Assert(!f.IsInfinite); OptionalSign SignificandSign; string SignificandText; OptionalSign ExponentSign; string ExponentText; string MantissaText = f.ToString(); Debug.Assert(MantissaText.Length > 0 && (MantissaText[0] != '-' || MantissaText.Length > 1)); if (MantissaText[0] == '-') { SignificandSign = OptionalSign.Negative; SignificandText = MantissaText.Substring(1); } else { SignificandSign = OptionalSign.None; SignificandText = MantissaText; } ExponentSign = OptionalSign.None; ExponentText = IntegerBase.Zero; CanonicalNumber Result = new CanonicalNumber(SignificandSign, SignificandText, ExponentSign, ExponentText); return(Result); }
/// <summary> /// Initializes a new instance of the <see cref="FormattedNumber"/> class. /// </summary> /// <param name="canonical">The canonical form of the number.</param> internal static FormattedNumber FromCanonical(CanonicalNumber canonical) { if (canonical == CanonicalNumber.NaN) { return(NaN); } if (canonical == CanonicalNumber.PositiveInfinity) { return(PositiveInfinity); } if (canonical == CanonicalNumber.NegativeInfinity) { return(NegativeInfinity); } string SignificandText = canonical.SignificandText; int SeparatorOffset = SignificandText.IndexOf(Parser.NeutralDecimalSeparator); string IntegerText; char SeparatorCharacter; string FractionalText; if (SeparatorOffset > 0) { IntegerText = SignificandText.Substring(0, SeparatorOffset); SeparatorCharacter = Parser.DecimalSeparator; FractionalText = SignificandText.Substring(SeparatorOffset + 1); } else { IntegerText = SignificandText; SeparatorCharacter = Parser.NoSeparator; FractionalText = string.Empty; } return(new FormattedReal(canonical.SignificandSign, 0, IntegerText, SeparatorCharacter, FractionalText, 'e', canonical.ExponentSign, canonical.ExponentText, string.Empty, canonical)); }
/// <summary> /// Returns this object's value raised to the power x. /// </summary> /// <param name="x">The number.</param> public CanonicalNumber Pow(CanonicalNumber x) { return(FromEFloat(NumberFloat.Pow(x.NumberFloat))); }
/// <summary> /// Initializes a new instance of the <see cref="FormattedReal"/> class. /// </summary> /// <param name="sign">The optional sign.</param> /// <param name="leadingZeroCount">The number of leading zeroes.</param> /// <param name="integerText">The text before the decimal separator character. Can be empty.</param> /// <param name="separatorCharacter">The decimal separator character. Can be <see cref="Parser.NoSeparator"/>.</param> /// <param name="fractionalText">The text after the decimal separator character and before the exponent. Can be empty.</param> /// <param name="exponentCharacter">The exponent character (e or E). Can be <see cref="Parser.NoSeparator"/>.</param> /// <param name="exponentSign">The optional exponent sign.</param> /// <param name="exponentText">The text after the exponent character. Can be empty.</param> /// <param name="invalidText">The trailing invalid text, if any.</param> /// <param name="canonical">The canonical form of the number.</param> /// <exception cref="NullReferenceException"><paramref name="invalidText"/> or <paramref name="canonical"/> is null.</exception> internal FormattedReal(OptionalSign sign, int leadingZeroCount, string integerText, char separatorCharacter, string fractionalText, char exponentCharacter, OptionalSign exponentSign, string exponentText, string invalidText, CanonicalNumber canonical) : base(invalidText, canonical) { Sign = sign; LeadingZeroCount = leadingZeroCount; IntegerText = integerText ?? throw new ArgumentNullException(nameof(integerText), "Value cannot be null."); SeparatorCharacter = separatorCharacter; FractionalText = fractionalText ?? throw new ArgumentNullException(nameof(fractionalText), "Value cannot be null."); ExponentCharacter = exponentCharacter; ExponentSign = exponentSign; ExponentText = exponentText ?? throw new ArgumentNullException(nameof(exponentText), "Value cannot be null."); if (leadingZeroCount < 0) { throw new ArgumentOutOfRangeException(nameof(leadingZeroCount)); } if (SeparatorCharacter != Parser.NoSeparator) { if (integerText.Length + fractionalText.Length == 0) { throw new ArgumentException($"Either {nameof(integerText)} or {nameof(fractionalText)} must not be empty."); } } else { if (integerText.Length == 0) { throw new ArgumentException($"{nameof(integerText)} must not be empty."); } } if (exponentCharacter != Parser.NoSeparator) { if (exponentText.Length == 0) { throw new ArgumentException($"{nameof(exponentText)} must not be empty."); } } }
/// <summary> /// Checks if two numbers are equal. /// </summary> /// <param name="other">The other instance.</param> public virtual bool IsEqual(CanonicalNumber other) { return(SignificandSign == other.SignificandSign && SignificandText == other.SignificandText && ExponentSign == other.ExponentSign && ExponentText == other.ExponentText); }
/// <summary> /// Returns the sum of this number and another. /// </summary> /// <param name="other">The other number.</param> public CanonicalNumber Add(CanonicalNumber other) { CanonicalNumber Result = FromEFloat(NumberFloat + other.NumberFloat); return(Result); }
/// <summary> /// Returns the bitwise OR of this object's value and another. /// </summary> /// <param name="other">The other number.</param> public CanonicalNumber BitwiseXor(CanonicalNumber other) { return(FromEFloat(NumberFloat ^ other.NumberFloat)); }
/// <summary> /// Returns the bitwise AND of this object's value and another. /// </summary> /// <param name="other">The other number.</param> public CanonicalNumber BitwiseAnd(CanonicalNumber other) { return(FromEFloat(NumberFloat & other.NumberFloat)); }
/// <summary> /// Returns the remainder when this object's value is divided by another. /// </summary> /// <param name="other">The other number.</param> public CanonicalNumber Remainder(CanonicalNumber other) { return(FromEFloat(NumberFloat.Remainder(other.NumberFloat))); }
/// <summary> /// Returns the difference between this number and another. /// </summary> /// <param name="other">The other number.</param> public CanonicalNumber Subtract(CanonicalNumber other) { return(FromEFloat(NumberFloat - other.NumberFloat)); }
/// <summary> /// Returns the ratio of this number and another. /// </summary> /// <param name="other">The other number.</param> public CanonicalNumber Divide(CanonicalNumber other) { return(FromEFloat(NumberFloat / other.NumberFloat)); }
/// <summary> /// Returns the product of this number and another. /// </summary> /// <param name="other">The other number.</param> public CanonicalNumber Multiply(CanonicalNumber other) { return(FromEFloat(NumberFloat * other.NumberFloat)); }
/// <summary> /// Initializes a new instance of the <see cref="FormattedNumber"/> class. /// </summary> /// <param name="invalidText">The trailing invalid text, if any.</param> /// <param name="canonical">The canonical form of the number.</param> internal FormattedNumber(string invalidText, CanonicalNumber canonical) { InvalidText = invalidText; Canonical = canonical; }
/// <summary> /// Initializes a new instance of the <see cref="FormattedInteger"/> class. /// </summary> /// <param name="integerBase">The base.</param> /// <param name="sign">The optional sign.</param> /// <param name="leadingZeroCount">The number of leading zeroes.</param> /// <param name="integerText">The integer text..</param> /// <param name="invalidText">The trailing invalid text, if any.</param> /// <param name="canonical">The canonical form of the number.</param> /// <exception cref="ArgumentOutOfRangeException"><paramref name="leadingZeroCount"/> is lesser than zero.</exception> internal FormattedInteger(IIntegerBase integerBase, OptionalSign sign, int leadingZeroCount, string integerText, string invalidText, CanonicalNumber canonical) : base(invalidText, canonical) { IntegerBase = integerBase; Sign = sign; LeadingZeroCount = leadingZeroCount; IntegerText = integerText; if (leadingZeroCount < 0) { throw new ArgumentOutOfRangeException(nameof(leadingZeroCount)); } }