using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; namespace Volian.Base.Library { [Serializable()] public class BigNum { #region fields private SortedDictionary _MyValue = new SortedDictionary(); private const ulong one = 1; private SortedDictionary MyValue { get { return _MyValue; } set { _MyValue = value; } } #endregion #region constructors public BigNum() { } public BigNum(int value) => SetFlag(value); public BigNum(string values) => SetFlags(values); public BigNum(ICollection values) => SetFlags(values); public override string ToString() { return FlagList; } #endregion #region operators public static BigNum operator |(BigNum bn1, BigNum bn2) { BigNum bn = new BigNum(bn1.GetFlags()); bn.SetFlags(bn2.GetFlags()); return bn; } public static BigNum operator &(BigNum bn1, BigNum bn2) { BigNum bn = new BigNum(0); foreach (uint k1 in bn1.MyValue.Keys) { if (bn2.MyValue.ContainsKey(k1) && (bn1.MyValue[k1] & bn2.MyValue[k1]) != 0) bn.MyValue[k1] = (bn1.MyValue[k1] & bn2.MyValue[k1]); } return bn; } #endregion #region methods public bool Includes(BigNum other) { List mine = GetFlags(); if (mine.Count == 0) return true; List yours = other.GetFlags(); if (yours.Count == 0) return false; foreach (int y in yours) if (mine.Contains(y)) return false; return true; } public void SetFlags(string values) { if (values == string.Empty) return; string[] myvalues = values.Split(','); foreach (string v in myvalues) SetFlag(int.Parse(v)); } public List GetFlags() { List myints = new List(); foreach (uint key in MyValue.Keys) { ulong y = MyValue[key]; for (int i = 0; i < 64; i++) { if (((y >> i) & one) == one) myints.Add((int)(i + (key * 64))); } } return myints; } public void SetFlag(int flag) { uint offset = (uint)(flag / 64); ulong x = one << (flag % 64); if (MyValue.ContainsKey(offset)) MyValue[offset] |= x; else MyValue.Add(offset, x); //} } public void SetFlags(ICollection flags) { foreach (int f in flags) SetFlag(f); } public static BigNum MakeBigNum(string numbers) => numbers == "-1" ? null : new BigNum(numbers); #endregion #region properties [XmlAttribute] public string FlagList { get { StringBuilder sb = new StringBuilder(); string sep = ""; foreach (int i in GetFlags()) { sb.Append(sep + i.ToString()); sep = ","; } return sb.ToString(); } set { SetFlags(value); } } #endregion } }