1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 using System.IO;
  8 
  9 namespace System.Numerics.Multiprecision
 10 {
 11     public class BigInt
 12     {
 13         public BigInt()
 14         {
 15             int errorStrHandle = -1;
 16             handle = RtCreateDefaultBigInt(errorStrHandle);
 17             if (handle == null)
 18             {
 19                 string error = RtGetString(errorStrHandle);
 20                 RtDisposeString(errorStrHandle);
 21                 throw Exception(error);
 22             }
 23         }
 24         public BigInt(int v)
 25         {
 26             int errorStrHandle = -1;
 27             handle = RtCreateBigIntFromInt(verrorStrHandle);
 28             if (handle == null)
 29             {
 30                 string error = RtGetString(errorStrHandle);
 31                 RtDisposeString(errorStrHandle);
 32                 throw Exception(error);
 33             }
 34         }
 35         public BigInt(uint v)
 36         {
 37             int errorStrHandle = -1;
 38             handle = RtCreateBigIntFromUInt(verrorStrHandle);
 39             if (handle == null)
 40             {
 41                 string error = RtGetString(errorStrHandle);
 42                 RtDisposeString(errorStrHandle);
 43                 throw Exception(error);
 44             }
 45         }
 46         public BigInt(long v)
 47         {
 48             int errorStrHandle = -1;
 49             handle = RtCreateBigIntFromLong(verrorStrHandle);
 50             if (handle == null)
 51             {
 52                 string error = RtGetString(errorStrHandle);
 53                 RtDisposeString(errorStrHandle);
 54                 throw Exception(error);
 55             }
 56         }
 57         public BigInt(ulong v)
 58         {
 59             int errorStrHandle = -1;
 60             handle = RtCreateBigIntFromULong(verrorStrHandle);
 61             if (handle == null)
 62             {
 63                 string error = RtGetString(errorStrHandle);
 64                 RtDisposeString(errorStrHandle);
 65                 throw Exception(error);
 66             }
 67         }
 68         public BigInt(const string& v)
 69         {
 70             int errorStrHandle = -1;
 71             handle = RtCreateBigIntFromStr(v.Chars()errorStrHandle);
 72             if (handle == null)
 73             {
 74                 string error = RtGetString(errorStrHandle);
 75                 RtDisposeString(errorStrHandle);
 76                 throw Exception(error);
 77             }
 78         }
 79         public BigInt(const BigInt& v)
 80         {
 81             int errorStrHandle = -1;
 82             handle = RtCreateBigIntFromCopy(v.handleerrorStrHandle);
 83             if (handle == null)
 84             {
 85                 string error = RtGetString(errorStrHandle);
 86                 RtDisposeString(errorStrHandle);
 87                 throw Exception(error);
 88             }
 89         }
 90         public void operator=(const BigInt& v)
 91         {
 92             if (handle == v.handle) return;
 93             if (handle != null)
 94             {
 95                 RtDestroyBigInt(handle);
 96             }
 97             int errorStrHandle = -1;
 98             handle = RtCreateBigIntFromCopy(v.handleerrorStrHandle);
 99             if (handle == null)
100             {
101                 string error = RtGetString(errorStrHandle);
102                 RtDisposeString(errorStrHandle);
103                 throw Exception(error);
104             }
105         }
106         public nothrow BigInt(BigInt&& that) : handle(that.handle)
107         {
108             that.handle = null;
109         }
110         public nothrow BigInt(void* handle_) : handle(handle_)
111         {
112         }
113         public default nothrow void operator=(BigInt&&);
114         public ~BigInt()
115         {
116             if (handle != null)
117             {
118                 RtDestroyBigInt(handle);
119             }
120         }
121         public string ToString() const
122         {
123             int errorStrHandle = -1;
124             const char* p = RtBigIntToCharPtr(handleerrorStrHandle);
125             if (p == null)
126             {
127                 string error = RtGetString(errorStrHandle);
128                 RtDisposeString(errorStrHandle);
129                 throw Exception(error);
130             }
131             string s = p;
132             RtDeleteCharPtr(p);
133             return s;
134         }
135         public int ToInt() const
136         {
137             int errorStrHandle = -1;
138             int v = RtBigIntToInt(handleerrorStrHandle);
139             if (errorStrHandle != -1)
140             {
141                 string error = RtGetString(errorStrHandle);
142                 RtDisposeString(errorStrHandle);
143                 throw Exception(error);
144             }
145             return v;
146         }
147         public uint ToUInt() const
148         {
149             int errorStrHandle = -1;
150             uint v = RtBigIntToUInt(handleerrorStrHandle);
151             if (errorStrHandle != -1)
152             {
153                 string error = RtGetString(errorStrHandle);
154                 RtDisposeString(errorStrHandle);
155                 throw Exception(error);
156             }
157             return v;
158         }
159         public long ToLong() const
160         {
161             int errorStrHandle = -1;
162             long v = RtBigIntToLong(handleerrorStrHandle);
163             if (errorStrHandle != -1)
164             {
165                 string error = RtGetString(errorStrHandle);
166                 RtDisposeString(errorStrHandle);
167                 throw Exception(error);
168             }
169             return v;
170         }
171         public ulong ToULong() const
172         {
173             int errorStrHandle = -1;
174             ulong v = RtBigIntToULong(handleerrorStrHandle);
175             if (errorStrHandle != -1)
176             {
177                 string error = RtGetString(errorStrHandle);
178                 RtDisposeString(errorStrHandle);
179                 throw Exception(error);
180             }
181             return v;
182         }
183         public inline nothrow void* Handle() const
184         {
185             return handle;
186         }
187         private void* handle;
188     }
189     
190     public BigInt operator-(const BigInt& x)
191     {
192         int errorStrHandle = -1;
193         void* handle = RtNegBigInt(x.Handle()errorStrHandle);
194         if (handle == null)
195         {
196             string error = RtGetString(errorStrHandle);
197             RtDisposeString(errorStrHandle);
198             throw Exception(error);
199         }
200         return BigInt(handle);
201     }
202     
203     public BigInt operator+(const BigInt& x)
204     {
205         int errorStrHandle = -1;
206         void* handle = RtPosBigInt(x.Handle()errorStrHandle);
207         if (handle == null)
208         {
209             string error = RtGetString(errorStrHandle);
210             RtDisposeString(errorStrHandle);
211             throw Exception(error);
212         }
213         return BigInt(handle);
214     }
215 
216     public BigInt operator~(const BigInt& x)
217     {
218         int errorStrHandle = -1;
219         void* handle = RtCplBigInt(x.Handle()errorStrHandle);
220         if (handle == null)
221         {
222             string error = RtGetString(errorStrHandle);
223             RtDisposeString(errorStrHandle);
224             throw Exception(error);
225         }
226         return BigInt(handle);
227     }
228     
229     public BigInt operator+(const BigInt& leftconst BigInt& right)
230     {
231         int errorStrHandle = -1;
232         void* handle = RtAddBigInt(left.Handle()right.Handle()errorStrHandle);
233         if (handle == null)
234         {
235             string error = RtGetString(errorStrHandle);
236             RtDisposeString(errorStrHandle);
237             throw Exception(error);
238         }
239         return BigInt(handle);
240     }
241     
242     public BigInt operator-(const BigInt& leftconst BigInt& right)
243     {
244         int errorStrHandle = -1;
245         void* handle = RtSubBigInt(left.Handle()right.Handle()errorStrHandle);
246         if (handle == null)
247         {
248             string error = RtGetString(errorStrHandle);
249             RtDisposeString(errorStrHandle);
250             throw Exception(error);
251         }
252         return BigInt(handle);
253     }
254     
255     public BigInt operator*(const BigInt& leftconst BigInt& right)
256     {
257         int errorStrHandle = -1;
258         void* handle = RtMulBigInt(left.Handle()right.Handle()errorStrHandle);
259         if (handle == null)
260         {
261             string error = RtGetString(errorStrHandle);
262             RtDisposeString(errorStrHandle);
263             throw Exception(error);
264         }
265         return BigInt(handle);
266     }
267     
268     public BigInt operator/(const BigInt& leftconst BigInt& right)
269     {
270         int errorStrHandle = -1;
271         void* handle = RtDivBigInt(left.Handle()right.Handle()errorStrHandle);
272         if (handle == null)
273         {
274             string error = RtGetString(errorStrHandle);
275             RtDisposeString(errorStrHandle);
276             throw Exception(error);
277         }
278         return BigInt(handle);
279     }
280     
281     public BigInt operator%(const BigInt& leftconst BigInt& right)
282     {
283         int errorStrHandle = -1;
284         void* handle = RtModBigInt(left.Handle()right.Handle()errorStrHandle);
285         if (handle == null)
286         {
287             string error = RtGetString(errorStrHandle);
288             RtDisposeString(errorStrHandle);
289             throw Exception(error);
290         }
291         return BigInt(handle);
292     }
293 
294     public BigInt operator&(const BigInt& leftconst BigInt& right)
295     {
296         int errorStrHandle = -1;
297         void* handle = RtAndBigInt(left.Handle()right.Handle()errorStrHandle);
298         if (handle == null)
299         {
300             string error = RtGetString(errorStrHandle);
301             RtDisposeString(errorStrHandle);
302             throw Exception(error);
303         }
304         return BigInt(handle);
305     }
306     
307     public BigInt operator|(const BigInt& leftconst BigInt& right)
308     {
309         int errorStrHandle = -1;
310         void* handle = RtOrBigInt(left.Handle()right.Handle()errorStrHandle);
311         if (handle == null)
312         {
313             string error = RtGetString(errorStrHandle);
314             RtDisposeString(errorStrHandle);
315             throw Exception(error);
316         }
317         return BigInt(handle);
318     }
319 
320     public BigInt operator^(const BigInt& leftconst BigInt& right)
321     {
322         int errorStrHandle = -1;
323         void* handle = RtXorBigInt(left.Handle()right.Handle()errorStrHandle);
324         if (handle == null)
325         {
326             string error = RtGetString(errorStrHandle);
327             RtDisposeString(errorStrHandle);
328             throw Exception(error);
329         }
330         return BigInt(handle);
331     }
332 
333     public BigInt operator<<(const BigInt& leftint right)
334     {
335         int errorStrHandle = -1;
336         void* handle = RtShiftLeftBigInt(left.Handle()righterrorStrHandle);
337         if (handle == null)
338         {
339             string error = RtGetString(errorStrHandle);
340             RtDisposeString(errorStrHandle);
341             throw Exception(error);
342         }
343         return BigInt(handle);
344     }
345 
346     public BigInt operator>>(const BigInt& leftint right)
347     {
348         int errorStrHandle = -1;
349         void* handle = RtShiftRightBigInt(left.Handle()righterrorStrHandle);
350         if (handle == null)
351         {
352             string error = RtGetString(errorStrHandle);
353             RtDisposeString(errorStrHandle);
354             throw Exception(error);
355         }
356         return BigInt(handle);
357     }
358     
359     public bool operator==(const BigInt& leftconst BigInt& right)
360     {
361         int errorStrHandle = -1;
362         bool result = RtEqualBigInt(left.Handle()right.Handle()errorStrHandle);
363         if (errorStrHandle != -1)
364         {
365             string error = RtGetString(errorStrHandle);
366             RtDisposeString(errorStrHandle);
367             throw Exception(error);
368         }
369         return result;
370     }
371 
372     public bool operator<(const BigInt& leftconst BigInt& right)
373     {
374         int errorStrHandle = -1;
375         bool result = RtLessBigInt(left.Handle()right.Handle()errorStrHandle);
376         if (errorStrHandle != -1)
377         {
378             string error = RtGetString(errorStrHandle);
379             RtDisposeString(errorStrHandle);
380             throw Exception(error);
381         }
382         return result;
383     }
384     
385     public TextWriter& operator<<(TextWriter& sconst BigInt& x)
386     {
387         return s << x.ToString();
388     }
389 }