1 using System;
2 using System.Numerics.Multiprecision;
3
4 namespace BigNumCalc
5 {
6 public enum BigNumKind
7 {
8 bigInt, bigRational, bigFloat
9 }
10
11 public nothrow BigNumKind CommonType(BigNumKind left, BigNumKind right)
12 {
13 switch (left)
14 {
15 case BigNumKind.bigInt:
16 {
17 switch (right)
18 {
19 case BigNumKind.bigInt: return BigNumKind.bigInt;
20 case BigNumKind.bigRational: return BigNumKind.bigRational;
21 case BigNumKind.bigFloat: return BigNumKind.bigFloat;
22 }
23 break;
24 }
25 case BigNumKind.bigRational:
26 {
27 switch (right)
28 {
29 case BigNumKind.bigInt: return BigNumKind.bigRational;
30 case BigNumKind.bigRational: return BigNumKind.bigRational;
31 case BigNumKind.bigFloat: return BigNumKind.bigFloat;
32 }
33 break;
34 }
35 case BigNumKind.bigFloat:
36 {
37 switch (right)
38 {
39 case BigNumKind.bigInt: return BigNumKind.bigFloat;
40 case BigNumKind.bigRational: return BigNumKind.bigFloat;
41 case BigNumKind.bigFloat: return BigNumKind.bigFloat;
42 }
43 break;
44 }
45 }
46 return BigNumKind.bigInt;
47 }
48
49 public abstract class BigValue
50 {
51 public virtual default ~BigValue();
52 public abstract nothrow BigNumKind Kind() const;
53 public abstract BigValue* As(BigNumKind kind) const;
54 public abstract string ToString() const;
55 }
56
57 public class BigIntValue : BigValue
58 {
59 public typedef BigInt OperandType;
60 public nothrow BigIntValue() : value()
61 {
62 }
63 public explicit nothrow BigIntValue(const BigInt& value_) : value(value_)
64 {
65 }
66 public override nothrow BigNumKind Kind() const
67 {
68 return BigNumKind.bigInt;
69 }
70 public override BigValue* As(BigNumKind kind) const
71 {
72 switch (kind)
73 {
74 case BigNumKind.bigInt:
75 {
76 return new BigIntValue(value);
77 }
78 case BigNumKind.bigRational:
79 {
80 BigRational val(value);
81 return new BigRationalValue(val);
82 }
83 case BigNumKind.bigFloat:
84 {
85 BigFloat val(value);
86 return new BigFloatValue(val);
87 }
88 }
89 return null;
90 }
91 public override string ToString() const
92 {
93 return value.ToString();
94 }
95 public inline nothrow const BigInt& Get() const
96 {
97 return value;
98 }
99 private BigInt value;
100 }
101
102 public class BigRationalValue : BigValue
103 {
104 public typedef BigRational OperandType;
105 public nothrow BigRationalValue() : value()
106 {
107 }
108 public explicit nothrow BigRationalValue(const BigRational& value_) : value(value_)
109 {
110 }
111 public override nothrow BigNumKind Kind() const
112 {
113 return BigNumKind.bigRational;
114 }
115 public override BigValue* As(BigNumKind kind) const
116 {
117 switch (kind)
118 {
119 case BigNumKind.bigRational:
120 {
121 return new BigRationalValue(value);
122 }
123 case BigNumKind.bigFloat:
124 {
125 BigFloat val(value);
126 return new BigFloatValue(val);
127 }
128 }
129 return null;
130 }
131 public override string ToString() const
132 {
133 return "[" + value.ToString() + "]";
134 }
135 public inline nothrow const BigRational& Get() const
136 {
137 return value;
138 }
139 private BigRational value;
140 }
141
142 public class BigFloatValue : BigValue
143 {
144 public typedef BigFloat OperandType;
145 public nothrow BigFloatValue() : value()
146 {
147 }
148 public explicit nothrow BigFloatValue(const BigFloat& value_) : value(value_)
149 {
150 }
151 public override nothrow BigNumKind Kind() const
152 {
153 return BigNumKind.bigFloat;
154 }
155 public override BigValue* As(BigNumKind kind) const
156 {
157 switch (kind)
158 {
159 case BigNumKind.bigFloat:
160 {
161 return new BigFloatValue(value);
162 }
163 }
164 return null;
165 }
166 public override string ToString() const
167 {
168 return value.ToString();
169 }
170 public inline nothrow const BigFloat& Get() const
171 {
172 return value;
173 }
174 private BigFloat value;
175 }
176 }
177