119 lines
2.7 KiB
C#
119 lines
2.7 KiB
C#
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<uint, ulong> _MyValue = new SortedDictionary<uint, ulong>();
|
|
private const ulong one = 1;
|
|
private SortedDictionary<uint, ulong> 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<int> 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<int> mine = GetFlags();
|
|
if (mine.Count == 0) return true;
|
|
List<int> 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<int> GetFlags()
|
|
{
|
|
List<int> myints = new List<int>();
|
|
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<int> 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
|
|
}
|
|
}
|