Introduction
IPluralNumber represents features of a string that contains a number.
/// <summary>
/// Interface for numbers that have decimal string representation or truncated approximation.
/// Base 2, 8 and 16 numbers are used aswell.
///
/// This interface is for extracting features for the purpose of language string declinations, not mathematical operations.
/// For example numbers "1.1" and "1.10" are not equal in linquistic sense.
///
/// Following features are extracted:
/// <list type="bullet">
/// <item>sign</item>
/// <item>integer digits</item>
/// <item>fraction digits</item>
/// <item>exponent sign and digits</item>
/// <item>exponent sign and digits</item>
/// </list>
/// ///
/// The IEnumerable<char> returns characters in canonicalized form with the following rules:
/// <list type="bullet">
/// <item>Starts with '-' if is negative</item>
/// <item>Decimal separator is '.'</item>
/// <item>There is no whitespaces</item>
/// <item>Exponent is unwrapped so that is adjusts the location of decimal separator.</item>
/// <item>Hexdecimals are in capital 'A' to 'F'</item>
/// </list>
/// ToString() also returns the same canonical characters.
/// </summary>
public interface IPluralNumber : IEnumerable<char>
{
/// <summary>Has a value. If value is NaN, returns false.</summary>
bool HasValue { get; }
/// <summary>Has decimal fractions. For example "0.10" is true, but "0.00" is false</summary>
bool IsFloat { get; }
/// <summary>Sign of the value, -1, 0 or 1.</summary>
/// <remarks>If sign is 0, then text represents zero value.</remarks>
int Sign { get; }
/// <summary>Base of digits, 2, 8, 10 or 16.</summary>
int Base { get; }
/// <summary>Absolute positive value characters. Excludes '-' and preceding and trailing zeros '000'.</summary>
IPluralNumber N { get; }
/// <summary>Integer digits.</summary>
IPluralNumber I { get; }
/// <summary>Exponent digits.</summary>
IPluralNumber E { get; }
/// <summary>Fraction digits including trailing zeros in the open format (exponent removed).</summary>
IPluralNumber F { get; }
/// <summary>Fraction digits excluding trailing zeros in the open format (exponent removed).</summary>
IPluralNumber T { get; }
/// <summary>Fraction digit count including trailing zeroes in the open format (exponent removed).</summary>
IPluralNumber V { get; }
/// <summary>Fraction digit count excluding trailing zeros in the open format (exponent removed).</summary>
IPluralNumber W { get; }
/// <summary>Integer digits.</summary>
int I_Digits { get; }
/// <summary>Exponent digits</summary>
int E_Digits { get; }
/// <summary>Fraction digits including trailing zeroes.</summary>
int F_Digits { get; }
/// <summary>Fraction digits excluding trailing zeros.</summary>
int T_Digits { get; }
/// <summary>Calculate modulo.</summary>
/// <returns>modulo</returns>
IPluralNumber Modulo(int modulo);
/// <summary>
/// Try to read as long.
///
/// If value doesn't fit or has floating-point fractions, then false.
/// If value is floating-point but fractions are zero "1.00", then returns true provided it fits long.
/// </summary>
bool TryGet(out long value);
/// <summary>
/// Try to read as decimal.
///
/// If value doesn't fit decimal, then returns false.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
bool TryGet(out decimal value);
/// <summary>
/// Try to read as double.
///
/// If value doesn't fit double, then returns false.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
bool TryGet(out double value);
/// <summary>
/// Try to read as big integer.
///
/// If value doesn't fit or has floating-point fractions, then
/// If value is floating-point but fractions are zero "1.00", then returns true provided it fits long.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
bool TryGet(out System.Numerics.BigInteger value);
}
TextNumber(memory) creates a struct that extracts number features from a ReadOnlyMemory<char>.
IFormatProvider culture = CultureInfo.InvariantCulture;
TextNumber number = new TextNumber("1,000,012.000678", culture);
WriteLine($"Integer digit count = {number.I_Digits}"); // 7
WriteLine($"Fraction digit count = {number.F_Digits}"); // 6
TextNumber(memory, culture) creates number features from a text literal of specific culture.
IFormatProvider culture = CultureInfo.GetCultureInfo("fi");
TextNumber number = new TextNumber("1.000.012,000678", culture);
WriteLine($"Integer digit count = {number.I_Digits}"); // 7
WriteLine($"Fraction digit count = {number.F_Digits}"); // 6
DoubleNumber(value, TextNumber) extracts number features of a double.
IFormatProvider culture = CultureInfo.GetCultureInfo("fi");
double value = 1_000_012.000678;
string text = value.ToString(culture);
TextNumber textNumber = new TextNumber(text, culture);
DoubleNumber number = new DoubleNumber(value, textNumber);
WriteLine($"Integer digit count = {number.I_Digits}"); // 7
WriteLine($"Fraction digit count = {number.F_Digits}"); // 6
LongNumber(value, TextNumber) extracts number features of a long.
IFormatProvider culture = CultureInfo.GetCultureInfo("fi");
long value = 1_000_012;
string text = value.ToString(culture);
TextNumber textNumber = new TextNumber(text, culture);
LongNumber number = new LongNumber(value, textNumber);
WriteLine($"Integer digit count = {number.I_Digits}"); // 7
WriteLine($"Fraction digit count = {number.F_Digits}"); // 0
ULongNumber(value, TextNumber) extracts number features of a ulong.
IFormatProvider culture = CultureInfo.GetCultureInfo("fi");
ulong value = 1_000_012;
string text = value.ToString(culture);
TextNumber textNumber = new TextNumber(text, culture);
ULongNumber number = new ULongNumber(value, textNumber);
WriteLine($"Integer digit count = {number.I_Digits}"); // 7
WriteLine($"Fraction digit count = {number.F_Digits}"); // 0
Full Example
Full example
using System.Globalization;
using System.Numerics;
using Avalanche.Localization;
using Avalanche.Localization.Pluralization;
using static System.Console;
class pluralnumber
{
public static void Run()
{
{
// <01>
IFormatProvider culture = CultureInfo.InvariantCulture;
TextNumber number = new TextNumber("1,000,012.000678", culture);
WriteLine($"Integer digit count = {number.I_Digits}"); // 7
WriteLine($"Fraction digit count = {number.F_Digits}"); // 6
// </01>
}
{
// <02>
IFormatProvider culture = CultureInfo.GetCultureInfo("fi");
TextNumber number = new TextNumber("1.000.012,000678", culture);
WriteLine($"Integer digit count = {number.I_Digits}"); // 7
WriteLine($"Fraction digit count = {number.F_Digits}"); // 6
// </02>
}
{
// <03>
IFormatProvider culture = CultureInfo.GetCultureInfo("fi");
double value = 1_000_012.000678;
string text = value.ToString(culture);
TextNumber textNumber = new TextNumber(text, culture);
DoubleNumber number = new DoubleNumber(value, textNumber);
WriteLine($"Integer digit count = {number.I_Digits}"); // 7
WriteLine($"Fraction digit count = {number.F_Digits}"); // 6
// </03>
}
{
// <04>
IFormatProvider culture = CultureInfo.GetCultureInfo("fi");
long value = 1_000_012;
string text = value.ToString(culture);
TextNumber textNumber = new TextNumber(text, culture);
LongNumber number = new LongNumber(value, textNumber);
WriteLine($"Integer digit count = {number.I_Digits}"); // 7
WriteLine($"Fraction digit count = {number.F_Digits}"); // 0
// </04>
}
{
// <05>
IFormatProvider culture = CultureInfo.GetCultureInfo("fi");
ulong value = 1_000_012;
string text = value.ToString(culture);
TextNumber textNumber = new TextNumber(text, culture);
ULongNumber number = new ULongNumber(value, textNumber);
WriteLine($"Integer digit count = {number.I_Digits}"); // 7
WriteLine($"Fraction digit count = {number.F_Digits}"); // 0
// </05>
}
{
// <06>
IFormatProvider culture = CultureInfo.GetCultureInfo("fi");
BigInteger value = 1_000_012;
string text = value.ToString(culture);
TextNumber textNumber = new TextNumber(text, culture);
IPluralNumber number = new BigIntegerNumber(value, textNumber);
//WriteLine($"Integer digit count = {number.I_Digits}"); // 0
WriteLine($"Fraction digit count = {number.F_Digits}"); // 6
// </06>
}
}
}