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 BigFloat
 12     {
 13         public BigFloat()
 14         {
 15             int errorStrHandle = -1;
 16             handle = RtCreateDefaultBigFloat(errorStrHandle);
 17             if (handle == null)
 18             {
 19                 string error = RtGetString(errorStrHandle);
 20                 RtDisposeString(errorStrHandle);
 21                 throw Exception(error);
 22             }
 23         }
 24         public BigFloat(int v)
 25         {
 26             int errorStrHandle = -1;
 27             handle = RtCreateBigFloatFromInt(verrorStrHandle);
 28             if (handle == null)
 29             {
 30                 string error = RtGetString(errorStrHandle);
 31                 RtDisposeString(errorStrHandle);
 32                 throw Exception(error);
 33             }
 34         }
 35         public BigFloat(uint v)
 36         {
 37             int errorStrHandle = -1;
 38             handle = RtCreateBigFloatFromUInt(verrorStrHandle);
 39             if (handle == null)
 40             {
 41                 string error = RtGetString(errorStrHandle);
 42                 RtDisposeString(errorStrHandle);
 43                 throw Exception(error);
 44             }
 45         }
 46         public BigFloat(long v)
 47         {
 48             int errorStrHandle = -1;
 49             handle = RtCreateBigFloatFromLong(verrorStrHandle);
 50             if (handle == null)
 51             {
 52                 string error = RtGetString(errorStrHandle);
 53                 RtDisposeString(errorStrHandle);
 54                 throw Exception(error);
 55             }
 56         }
 57         public BigFloat(ulong v)
 58         {
 59             int errorStrHandle = -1;
 60             handle = RtCreateBigFloatFromULong(verrorStrHandle);
 61             if (handle == null)
 62             {
 63                 string error = RtGetString(errorStrHandle);
 64                 RtDisposeString(errorStrHandle);
 65                 throw Exception(error);
 66             }
 67         }
 68         public BigFloat(double v)
 69         {
 70             int errorStrHandle = -1;
 71             handle = RtCreateBigFloatFromDouble(verrorStrHandle);
 72             if (handle == null)
 73             {
 74                 string error = RtGetString(errorStrHandle);
 75                 RtDisposeString(errorStrHandle);
 76                 throw Exception(error);
 77             }
 78         }
 79         public nothrow BigFloat(BigFloat&& that) : handle(that.handle)
 80         {
 81             that.handle = null;
 82         }
 83         public BigFloat(const string& v)
 84         {
 85             int errorStrHandle = -1;
 86             handle = RtCreateBigFloatFromStr(v.Chars()errorStrHandle);
 87             if (handle == null)
 88             {
 89                 string error = RtGetString(errorStrHandle);
 90                 RtDisposeString(errorStrHandle);
 91                 throw Exception(error);
 92             }
 93         }
 94         public BigFloat(const BigFloat& v)
 95         {
 96             int errorStrHandle = -1;
 97             handle = RtCreateBigFloatFromCopy(v.handleerrorStrHandle);
 98             if (handle == null)
 99             {
100                 string error = RtGetString(errorStrHandle);
101                 RtDisposeString(errorStrHandle);
102                 throw Exception(error);
103             }
104         }
105         public void operator=(const BigFloat& v)
106         {
107             if (handle == v.handle) return;
108             if (handle != null)
109             {
110                 RtDestroyBigFloat(handle);
111             }
112             int errorStrHandle = -1;
113             handle = RtCreateBigFloatFromCopy(v.handleerrorStrHandle);
114             if (handle == null)
115             {
116                 string error = RtGetString(errorStrHandle);
117                 RtDisposeString(errorStrHandle);
118                 throw Exception(error);
119             }
120         }
121         public BigFloat(const BigInt& v)
122         {
123             int errorStrHandle = -1;
124             handle = RtCreateBigFloatFromBigInt(v.Handle()errorStrHandle);
125             if (handle == null)
126             {
127                 string error = RtGetString(errorStrHandle);
128                 RtDisposeString(errorStrHandle);
129                 throw Exception(error);
130             }
131         }
132         public BigFloat(const BigRational& v)
133         {
134             int errorStrHandle = -1;
135             handle = RtCreateBigFloatFromBigRational(v.Handle()errorStrHandle);
136             if (handle == null)
137             {
138                 string error = RtGetString(errorStrHandle);
139                 RtDisposeString(errorStrHandle);
140                 throw Exception(error);
141             }
142         }
143         public default nothrow void operator=(BigFloat&&);
144         public nothrow BigFloat(void* handle_) : handle(handle_)
145         {
146         }
147         public ~BigFloat()
148         {
149             if (handle != null)
150             {
151                 RtDestroyBigFloat(handle);
152             }
153         }
154         public string ToString() const
155         {
156             int errorStrHandle = -1;
157             const char* p = RtBigFloatToCharPtr(handleerrorStrHandle);
158             if (p == null)
159             {
160                 string error = RtGetString(errorStrHandle);
161                 RtDisposeString(errorStrHandle);
162                 throw Exception(error);
163             }
164             string s = p;
165             RtDeleteCharPtr(p);
166             return s;
167         }
168         public double ToDouble() const
169         {
170             int errorStrHandle = -1;
171             double result = RtBigFloatToDouble(handleerrorStrHandle);
172             if (errorStrHandle != -1)
173             {
174                 string error = RtGetString(errorStrHandle);
175                 RtDisposeString(errorStrHandle);
176                 throw Exception(error);
177             }
178             return result;
179         }
180         public BigInt ToBigInt() const
181         {
182             int errorStrHandle = -1;
183             void* bigIntHandle = RtBigFloatToBigInt(handleerrorStrHandle);
184             if (bigIntHandle == null)
185             {
186                 string error = RtGetString(errorStrHandle);
187                 RtDisposeString(errorStrHandle);
188                 throw Exception(error);
189             }
190             return BigInt(bigIntHandle);
191         }
192         public BigRational ToBigRational() const
193         {
194             int errorStrHandle = -1;
195             void* bigRationalHandle = RtBigFloatToBigRational(handleerrorStrHandle);
196             if (bigRationalHandle == null)
197             {
198                 string error = RtGetString(errorStrHandle);
199                 RtDisposeString(errorStrHandle);
200                 throw Exception(error);
201             }
202             return BigRational(bigRationalHandle);
203         }
204         public inline nothrow void* Handle() const
205         {
206             return handle;
207         }
208         private void* handle;
209     }
210     
211     public BigFloat operator-(const BigFloat& x)
212     {
213         int errorStrHandle = -1;
214         void* handle = RtNegBigFloat(x.Handle()errorStrHandle);
215         if (handle == null)
216         {
217             string error = RtGetString(errorStrHandle);
218             RtDisposeString(errorStrHandle);
219             throw Exception(error);
220         }
221         return BigFloat(handle);
222     }
223 
224     public BigFloat operator+(const BigFloat& x)
225     {
226         int errorStrHandle = -1;
227         void* handle = RtPosBigFloat(x.Handle()errorStrHandle);
228         if (handle == null)
229         {
230             string error = RtGetString(errorStrHandle);
231             RtDisposeString(errorStrHandle);
232             throw Exception(error);
233         }
234         return BigFloat(handle);
235     }
236     
237     public BigFloat operator+(const BigFloat& leftconst BigFloat& right)
238     {
239         int errorStrHandle = -1;
240         void* handle = RtAddBigFloat(left.Handle()right.Handle()errorStrHandle);
241         if (handle == null)
242         {
243             string error = RtGetString(errorStrHandle);
244             RtDisposeString(errorStrHandle);
245             throw Exception(error);
246         }
247         return BigFloat(handle);
248     }
249     
250     public BigFloat operator-(const BigFloat& leftconst BigFloat& right)
251     {
252         int errorStrHandle = -1;
253         void* handle = RtSubBigFloat(left.Handle()right.Handle()errorStrHandle);
254         if (handle == null)
255         {
256             string error = RtGetString(errorStrHandle);
257             RtDisposeString(errorStrHandle);
258             throw Exception(error);
259         }
260         return BigFloat(handle);
261     }
262     
263     public BigFloat operator*(const BigFloat& leftconst BigFloat& right)
264     {
265         int errorStrHandle = -1;
266         void* handle = RtMulBigFloat(left.Handle()right.Handle()errorStrHandle);
267         if (handle == null)
268         {
269             string error = RtGetString(errorStrHandle);
270             RtDisposeString(errorStrHandle);
271             throw Exception(error);
272         }
273         return BigFloat(handle);
274     }
275     
276     public BigFloat operator/(const BigFloat& leftconst BigFloat& right)
277     {
278         int errorStrHandle = -1;
279         void* handle = RtDivBigFloat(left.Handle()right.Handle()errorStrHandle);
280         if (handle == null)
281         {
282             string error = RtGetString(errorStrHandle);
283             RtDisposeString(errorStrHandle);
284             throw Exception(error);
285         }
286         return BigFloat(handle);
287     }
288     
289     public bool operator==(const BigFloat& leftconst BigFloat& right)
290     {
291         int errorStrHandle = -1;
292         bool result = RtEqualBigFloat(left.Handle()right.Handle()errorStrHandle);
293         if (errorStrHandle != -1)
294         {
295             string error = RtGetString(errorStrHandle);
296             RtDisposeString(errorStrHandle);
297             throw Exception(error);
298         }
299         return result;
300     }
301 
302     public bool operator<(const BigFloat& leftconst BigFloat& right)
303     {
304         int errorStrHandle = -1;
305         bool result = RtLessBigFloat(left.Handle()right.Handle()errorStrHandle);
306         if (errorStrHandle != -1)
307         {
308             string error = RtGetString(errorStrHandle);
309             RtDisposeString(errorStrHandle);
310             throw Exception(error);
311         }
312         return result;
313     }
314 
315     public TextWriter& operator<<(TextWriter& writerconst BigFloat& x)
316     {
317         return writer << x.ToString();
318     }
319 }