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