3ec7d7b61362048993e40952892d875d02ec9db0
[NovacoinLibrary.git] / Novacoin / base_uint.cs
1 \feff/**
2 *  Novacoin classes library
3 *  Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
4
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.
9
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.
14
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/>.
17 */
18
19
20 using System;
21 using System.Diagnostics.Contracts;
22
23 namespace Novacoin
24 {
25     /// <summary>
26     /// Base class for uint256 and uint160.
27     /// </summary>
28     public class base_uint : IComparable<base_uint>, IEquatable<base_uint>
29     {
30         protected readonly int nWidth;
31         protected uint[] pn;
32
33         public double getDouble()
34         {
35             double ret = 0.0;
36             double fact = 1.0;
37
38             for (int i = 0; i < nWidth; i++)
39             {
40                 ret += fact * pn[i];
41                 fact *= 4294967296.0;
42             }
43
44             return ret;
45         }
46
47         public ulong GetLow64()
48         {
49             return pn[0] | (ulong)pn[1] << 32;
50         }
51
52         public uint GetLow32()
53         {
54             return pn[0];
55         }
56
57         public int Size
58         {
59             get
60             {
61                 return nWidth;
62             }
63         }
64
65         public static bool operator !(base_uint a)
66         {
67             for (int i = 0; i < a.nWidth; i++)
68             {
69                 if (a.pn[i] != 0)
70                 {
71                     return false;
72                 }
73             }
74             return true;
75         }
76
77
78         public static bool operator <(base_uint a, base_uint b)
79         {
80             for (int i = a.nWidth - 1; i >= 0; i--)
81             {
82                 if (a.pn[i] < b.pn[i])
83                 {
84                     return true;
85                 }
86                 else if (a.pn[i] > b.pn[i])
87                 {
88                     return false;
89                 }
90             }
91             return false;
92         }
93
94         public static bool operator <=(base_uint a, base_uint b)
95         {
96             for (int i = a.nWidth - 1; i >= 0; i--)
97             {
98                 if (a.pn[i] < b.pn[i])
99                 {
100                     return true;
101                 }
102                 else if (a.pn[i] > b.pn[i])
103                 {
104                     return false;
105                 }
106             }
107             return true;
108         }
109
110         public static bool operator >(base_uint a, base_uint b)
111         {
112             for (int i = a.nWidth - 1; i >= 0; i--)
113             {
114                 if (a.pn[i] > b.pn[i])
115                 {
116                     return true;
117                 }
118                 else if (a.pn[i] < b.pn[i])
119                 {
120                     return false;
121                 }
122             }
123             return false;
124         }
125
126         public static bool operator >=(base_uint a, base_uint b)
127         {
128             for (int i = a.nWidth - 1; i >= 0; i--)
129             {
130                 if (a.pn[i] > b.pn[i])
131                 {
132                     return true;
133                 }
134                 else if (a.pn[i] < b.pn[i])
135                 {
136                     return false;
137                 }
138             }
139             return true;
140         }
141
142         public static bool operator ==(base_uint a, base_uint b)
143         {
144             if (object.ReferenceEquals(a, b))
145             {
146                 return true;
147             }
148
149             for (int i = 0; i < a.nWidth; i++)
150             {
151                 if (a.pn[i] != b.pn[i])
152                 {
153                     return false;
154                 }
155             }
156             return true;
157         }
158
159         public static bool operator ==(base_uint a, ulong b)
160         {
161             if (a.pn[0] != (uint)b)
162             {
163                 return false;
164             }
165
166             if (a.pn[1] != (uint)(b >> 32))
167             {
168                 return false;
169             }
170
171             for (int i = 2; i < a.nWidth; i++)
172             {
173                 if (a.pn[i] != 0)
174                 {
175                     return false;
176                 }
177             }
178             return true;
179         }
180
181         public static bool operator !=(base_uint a, base_uint b)
182         {
183             return (!(a == b));
184         }
185
186         public static bool operator !=(base_uint a, ulong b)
187         {
188             return (!(a == b));
189         }
190
191         public static bool operator true(base_uint a)
192         {
193             return (a != 0);
194         }
195
196         public static bool operator false(base_uint a)
197         {
198             return (a == 0);
199         }
200
201         public static implicit operator byte[] (base_uint a)
202         {
203             return Interop.LEBytes(a.pn);
204         }
205
206         private static bool ArraysEqual(uint[] a, uint[] b)
207         {
208             Contract.Requires<ArgumentException>(a.Length == b.Length, "Array length mismatch.");
209
210             for (int i = 0; i < a.Length; i++)
211             {
212                 if (a[i] != b[i])
213                 {
214                     return false;
215                 }
216             }
217             return true;
218         }
219
220         public override int GetHashCode()
221         {
222             int hash = 17;
223             unchecked
224             {
225                 foreach (var element in pn)
226                 {
227                     hash = hash * 31 + element.GetHashCode();
228                 }
229             }
230             return hash;
231         }
232
233         public int CompareTo(base_uint item)
234         {
235             if (this > item)
236             {
237                 return 1;
238             }
239             else if (this < item)
240             {
241                 return -1;
242             }
243
244             return 0;
245         }
246
247         public bool Equals(base_uint a)
248         {
249             if (a == null)
250             {
251                 return false;
252             }
253
254             return ArraysEqual(pn, a.pn);
255         }
256
257         public override bool Equals(object o)
258         {
259             return Equals(o as base_uint);
260         }
261
262         public override string ToString()
263         {
264             return Interop.ToHex(Interop.ReverseBytes(this));
265         }
266     }
267 }