2 * Novacoin classes library
3 * Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 using System.Collections.Generic;
22 using System.Diagnostics.Contracts;
27 /// Base class for uint256 and uint160.
29 public class base_uint : IComparable<base_uint>, IEquatable<base_uint>, IEqualityComparer<base_uint>
31 #region Internal representation
33 /// Length of internal representation
37 /// Big numbers are stored as array of unsigned 32-bit integers.
42 #region Helper properties
50 for (int i = 0; i < nWidth; i++)
62 get { return pn[0] | (ulong)pn[1] << 32; }
71 /// Total size in bytes.
77 return nWidth * sizeof(uint);
82 /// Zero or the position of highest non-zero bit plus one.
88 for (int pos = nWidth - 1; pos >= 0; pos--)
92 for (int bits = 31; bits > 0; bits--)
94 if ((pn[pos] & 1 << bits) != 0)
95 return 32 * pos + bits + 1;
107 /// Negation operator
109 /// <param name="a">Value</param>
110 /// <returns>True if value is zero, false otherwise.</returns>
111 public static bool operator !(base_uint a)
113 for (int i = 0; i < a.nWidth; i++)
124 #region Comparison operations
125 public static bool operator <(base_uint a, base_uint b)
127 for (int i = a.nWidth - 1; i >= 0; i--)
129 if (a.pn[i] < b.pn[i])
133 else if (a.pn[i] > b.pn[i])
141 public static bool operator <=(base_uint a, base_uint b)
143 for (int i = a.nWidth - 1; i >= 0; i--)
145 if (a.pn[i] < b.pn[i])
149 else if (a.pn[i] > b.pn[i])
157 public static bool operator >(base_uint a, base_uint b)
159 for (int i = a.nWidth - 1; i >= 0; i--)
161 if (a.pn[i] > b.pn[i])
165 else if (a.pn[i] < b.pn[i])
173 public static bool operator >=(base_uint a, base_uint b)
175 for (int i = a.nWidth - 1; i >= 0; i--)
177 if (a.pn[i] > b.pn[i])
181 else if (a.pn[i] < b.pn[i])
190 #region Equality operators
191 public static bool operator ==(base_uint a, base_uint b)
193 if (object.ReferenceEquals(a, b))
198 for (int i = 0; i < a.nWidth; i++)
200 if (a.pn[i] != b.pn[i])
208 public static bool operator ==(base_uint a, ulong b)
210 if (a.pn[0] != (uint)b)
215 if (a.pn[1] != (uint)(b >> 32))
220 for (int i = 2; i < a.nWidth; i++)
230 public static bool operator !=(base_uint a, base_uint b)
235 public static bool operator !=(base_uint a, ulong b)
241 #region Cast operations
243 /// True cast operator
245 /// <param name="a"></param>
246 /// <returns></returns>
247 public static bool operator true(base_uint a)
253 /// False cast operator.
255 /// <param name="a">Value</param>
256 /// <returns>Boolean result</returns>
257 public static bool operator false(base_uint a)
263 /// Imlicit byte[] cast operator.
265 /// <param name="a">Value</param>
266 public static implicit operator byte[] (base_uint a)
268 return Interop.LEBytes(a.pn);
273 /// Arrays equality checking helper method.
275 /// <param name="a">Array 1</param>
276 /// <param name="b">Array 2</param>
277 /// <returns>Result.</returns>
278 private static bool ArraysEqual(uint[] a, uint[] b)
280 Contract.Requires<ArgumentException>(a.Length == b.Length, "Array length mismatch.");
282 for (int i = 0; i < a.Length; i++)
293 #region IEqualityComparer
294 public bool Equals(base_uint a, base_uint b)
296 if (object.ReferenceEquals(a, b))
301 return ArraysEqual(a.pn, b.pn);
304 public int GetHashCode(base_uint a)
306 return a.GetHashCode();
312 public int CompareTo(base_uint item)
318 else if (this < item)
328 public bool Equals(base_uint a)
330 if (object.ReferenceEquals(a, null))
335 return ArraysEqual(pn, a.pn);
338 public override int GetHashCode()
343 foreach (var element in pn)
345 hash = hash * 31 + element.GetHashCode();
351 public override bool Equals(object o)
353 return Equals(o as base_uint);
358 /// Serialize to string.
360 /// <returns></returns>
361 public override string ToString()
363 return Interop.ToHex(Interop.ReverseBytes(this));