1 /*
2     SPDX-FileCopyrightText: 2001-2013 Evan Teran <evan.teran@gmail.com>
3     SPDX-FileCopyrightText: 2003-2005 Klaus Niederkrueger <kniederk@math.uni-koeln.de>
4 
5     SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #include "knumber.h"
9 #include <QString>
10 #include <cstdlib>
11 #include <iostream>
12 #include <limits>
13 
14 namespace
15 {
16 const int precision = 12;
17 
numtypeToString(int arg)18 QString numtypeToString(int arg)
19 {
20     switch (arg) {
21     case 0:
22         return QStringLiteral("Special");
23     case 1:
24         return QStringLiteral("Integer");
25     case 3:
26         return QStringLiteral("Fraction");
27     case 2:
28         return QStringLiteral("Float");
29     default:
30         return QLatin1String("Unknown:") + QString::number(arg);
31     }
32 }
33 
checkResult(const QString & string,const KNumber & result,const QString & desired_string,int desired)34 void checkResult(const QString &string, const KNumber &result, const QString &desired_string, int desired)
35 {
36     std::cout << "Testing result of: " << qPrintable(string) << " should give " << qPrintable(desired_string) << " and gives "
37               << qPrintable(result.toQString(precision)) << " ...\n";
38 
39     std::cout << "The type of the result should be " << qPrintable(numtypeToString(desired)) << " and gives " << qPrintable(numtypeToString(result.type()))
40               << " ... ";
41 
42     if (result.type() == desired && result.toQString(precision) == desired_string) {
43         std::cout << "OK\n";
44         return;
45     }
46 
47     std::cout << "Failed\n";
48     exit(1);
49 }
50 
checkTruth(const QString & string,bool computation,bool desired_result)51 void checkTruth(const QString &string, bool computation, bool desired_result)
52 {
53     std::cout << "Testing truth of: " << qPrintable(string) << " should be " << desired_result << " and is " << computation << " ... ";
54 
55     if (computation == desired_result) {
56         std::cout << "OK\n";
57         return;
58     }
59 
60     std::cout << "Failed\n";
61     exit(1);
62 }
63 
checkType(const QString & string,int test_arg,int desired)64 void checkType(const QString &string, int test_arg, int desired)
65 {
66     std::cout << "Testing type of: " << qPrintable(string) << " should give " << qPrintable(numtypeToString(desired)) << " and gives "
67               << qPrintable(numtypeToString(test_arg)) << " ...";
68 
69     if (test_arg == desired) {
70         std::cout << "OK\n";
71         return;
72     }
73 
74     std::cout << "Failed\n";
75     exit(1);
76 }
77 
testingCompare()78 void testingCompare()
79 {
80     std::cout << "\n\n";
81     std::cout << "Testing Compare:\n";
82     std::cout << "----------------\n";
83 
84     checkTruth(QStringLiteral("KNumber(5) == KNumber(2)"), KNumber(5) == KNumber(2), false);
85     checkTruth(QStringLiteral("KNumber(5) > KNumber(2)"), KNumber(5) > KNumber(2), true);
86     checkTruth(QStringLiteral("KNumber(5) < KNumber(2)"), KNumber(5) < KNumber(2), false);
87     checkTruth(QStringLiteral("KNumber(5) < KNumber(0)"), KNumber(5) < KNumber(0), false);
88     checkTruth(QStringLiteral("KNumber(-5) < KNumber(0)"), KNumber(-5) < KNumber(0), true);
89     checkTruth(QStringLiteral("KNumber(5) >= KNumber(2)"), KNumber(5) >= KNumber(2), true);
90     checkTruth(QStringLiteral("KNumber(5) <= KNumber(2)"), KNumber(5) <= KNumber(2), false);
91     checkTruth(QStringLiteral("KNumber(5) != KNumber(2)"), KNumber(5) != KNumber(2), true);
92 
93     checkTruth(QStringLiteral("KNumber(2) == KNumber(2)"), KNumber(2) == KNumber(2), true);
94     checkTruth(QStringLiteral("KNumber(2) > KNumber(2)"), KNumber(2) > KNumber(2), false);
95     checkTruth(QStringLiteral("KNumber(2) < KNumber(2)"), KNumber(2) < KNumber(2), false);
96     checkTruth(QStringLiteral("KNumber(2) >= KNumber(2)"), KNumber(2) >= KNumber(2), true);
97     checkTruth(QStringLiteral("KNumber(2) <= KNumber(2)"), KNumber(2) <= KNumber(2), true);
98     checkTruth(QStringLiteral("KNumber(2) != KNumber(2)"), KNumber(2) != KNumber(2), false);
99 
100     checkTruth(QStringLiteral("KNumber(5) == KNumber(\"1/2\")"), KNumber(5) == KNumber(QStringLiteral("1/2")), false);
101     checkTruth(QStringLiteral("KNumber(5) > KNumber(\"1/2\")"), KNumber(5) > KNumber(QStringLiteral("1/2")), true);
102     checkTruth(QStringLiteral("KNumber(5) < KNumber(\"1/2\")"), KNumber(5) < KNumber(QStringLiteral("1/2")), false);
103     checkTruth(QStringLiteral("KNumber(5) >= KNumber(\"1/2\")"), KNumber(5) >= KNumber(QStringLiteral("1/2")), true);
104     checkTruth(QStringLiteral("KNumber(5) <= KNumber(\"1/2\")"), KNumber(5) <= KNumber(QStringLiteral("1/2")), false);
105     checkTruth(QStringLiteral("KNumber(5) != KNumber(\"1/2\")"), KNumber(5) != KNumber(QStringLiteral("1/2")), true);
106 
107     checkTruth(QStringLiteral("KNumber(\"1/2\") == KNumber(\"1/2\")"), KNumber(QStringLiteral("1/2")) == KNumber(QStringLiteral("1/2")), true);
108     checkTruth(QStringLiteral("KNumber(\"1/2\") > KNumber(\"1/2\")"), KNumber(QStringLiteral("1/2")) > KNumber(QStringLiteral("1/2")), false);
109     checkTruth(QStringLiteral("KNumber(\"1/2\") < KNumber(\"1/2\")"), KNumber(QStringLiteral("1/2")) < KNumber(QStringLiteral("1/2")), false);
110     checkTruth(QStringLiteral("KNumber(\"1/2\") >= KNumber(\"1/2\")"), KNumber(QStringLiteral("1/2")) >= KNumber(QStringLiteral("1/2")), true);
111     checkTruth(QStringLiteral("KNumber(\"1/2\") <= KNumber(\"1/2\")"), KNumber(QStringLiteral("1/2")) <= KNumber(QStringLiteral("1/2")), true);
112     checkTruth(QStringLiteral("KNumber(\"1/2\") != KNumber(\"1/2\")"), KNumber(QStringLiteral("1/2")) != KNumber(QStringLiteral("1/2")), false);
113 
114     checkTruth(QStringLiteral("KNumber(\"3/2\") == KNumber(\"1/2\")"), KNumber(QStringLiteral("3/2")) == KNumber(QStringLiteral("1/2")), false);
115     checkTruth(QStringLiteral("KNumber(\"3/2\") > KNumber(\"1/2\")"), KNumber(QStringLiteral("3/2")) > KNumber(QStringLiteral("1/2")), true);
116     checkTruth(QStringLiteral("KNumber(\"3/2\") < KNumber(\"1/2\")"), KNumber(QStringLiteral("3/2")) < KNumber(QStringLiteral("1/2")), false);
117     checkTruth(QStringLiteral("KNumber(\"3/2\") >= KNumber(\"1/2\")"), KNumber(QStringLiteral("3/2")) >= KNumber(QStringLiteral("1/2")), true);
118     checkTruth(QStringLiteral("KNumber(\"3/2\") <= KNumber(\"1/2\")"), KNumber(QStringLiteral("3/2")) <= KNumber(QStringLiteral("1/2")), false);
119     checkTruth(QStringLiteral("KNumber(\"3/2\") != KNumber(\"1/2\")"), KNumber(QStringLiteral("3/2")) != KNumber(QStringLiteral("1/2")), true);
120 
121     checkTruth(QStringLiteral("KNumber(3.2) != KNumber(3)"), KNumber(3.2) != KNumber(3), true);
122     checkTruth(QStringLiteral("KNumber(3.2) > KNumber(3)"), KNumber(3.2) > KNumber(3), true);
123     checkTruth(QStringLiteral("KNumber(3.2) < KNumber(3)"), KNumber(3.2) < KNumber(3), false);
124 
125     checkTruth(QStringLiteral("KNumber(3.2) < KNumber(\"3/5\")"), KNumber(3.2) < KNumber(QStringLiteral("3/5")), false);
126 }
127 
testingAdditions()128 void testingAdditions()
129 {
130     std::cout << "\n\n";
131     std::cout << "Testing additions:\n";
132     std::cout << "------------------\n";
133 
134     checkResult(QStringLiteral("KNumber(5) + KNumber(2)"), KNumber(5) + KNumber(2), QStringLiteral("7"), KNumber::TYPE_INTEGER);
135     checkResult(QStringLiteral("KNumber(5) + KNumber(\"2/3\")"), KNumber(5) + KNumber(QStringLiteral("2/3")), QStringLiteral("17/3"), KNumber::TYPE_FRACTION);
136     checkResult(QStringLiteral("KNumber(5) + KNumber(\"2.3\")"), KNumber(5) + KNumber(QStringLiteral("2.3")), QStringLiteral("7.3"), KNumber::TYPE_FLOAT);
137 
138     checkResult(QStringLiteral("KNumber(\"5/3\") + KNumber(2)"), KNumber(QStringLiteral("5/3")) + KNumber(2), QStringLiteral("11/3"), KNumber::TYPE_FRACTION);
139     checkResult(QStringLiteral("KNumber(\"5/3\") + KNumber(\"2/3\")"),
140                 KNumber(QStringLiteral("5/3")) + KNumber(QStringLiteral("2/3")),
141                 QStringLiteral("7/3"),
142                 KNumber::TYPE_FRACTION);
143     checkResult(QStringLiteral("KNumber(\"5/3\") + KNumber(\"1/3\")"),
144                 KNumber(QStringLiteral("5/3")) + KNumber(QStringLiteral("1/3")),
145                 QStringLiteral("2"),
146                 KNumber::TYPE_INTEGER);
147     checkResult(QStringLiteral("KNumber(\"5/3\") + KNumber(\"-26/3\")"),
148                 KNumber(QStringLiteral("5/3")) + KNumber(QStringLiteral("-26/3")),
149                 QStringLiteral("-7"),
150                 KNumber::TYPE_INTEGER);
151     checkResult(QStringLiteral("KNumber(\"5/2\") + KNumber(2.3)"), KNumber(QStringLiteral("5/2")) + KNumber(2.3), QStringLiteral("4.8"), KNumber::TYPE_FLOAT);
152 
153     checkResult(QStringLiteral("KNumber(5.3) + KNumber(2)"), KNumber(5.3) + KNumber(2), QStringLiteral("7.3"), KNumber::TYPE_FLOAT);
154     checkResult(QStringLiteral("KNumber(5.3) + KNumber(\"2/4\")"), KNumber(5.3) + KNumber(QStringLiteral("2/4")), QStringLiteral("5.8"), KNumber::TYPE_FLOAT);
155     checkResult(QStringLiteral("KNumber(5.3) + KNumber(2.3)"), KNumber(5.3) + KNumber(2.3), QStringLiteral("7.6"), KNumber::TYPE_FLOAT);
156 }
157 
testingSubtractions()158 void testingSubtractions()
159 {
160     std::cout << "\n\n";
161     std::cout << "Testing subtractions:\n";
162     std::cout << "---------------------\n";
163 
164     checkResult(QStringLiteral("KNumber(5) - KNumber(2)"), KNumber(5) - KNumber(2), QStringLiteral("3"), KNumber::TYPE_INTEGER);
165     checkResult(QStringLiteral("KNumber(5) - KNumber(\"2/3\")"), KNumber(5) - KNumber(QStringLiteral("2/3")), QStringLiteral("13/3"), KNumber::TYPE_FRACTION);
166     checkResult(QStringLiteral("KNumber(5) - KNumber(2.3)"), KNumber(5) - KNumber(2.3), QStringLiteral("2.7"), KNumber::TYPE_FLOAT);
167 
168     checkResult(QStringLiteral("KNumber(\"5/3\") - KNumber(2)"), KNumber(QStringLiteral("5/3")) - KNumber(2), QStringLiteral("-1/3"), KNumber::TYPE_FRACTION);
169     checkResult(QStringLiteral("KNumber(\"5/3\") - KNumber(\"1/3\")"),
170                 KNumber(QStringLiteral("5/3")) - KNumber(QStringLiteral("1/3")),
171                 QStringLiteral("4/3"),
172                 KNumber::TYPE_FRACTION);
173     checkResult(QStringLiteral("KNumber(\"5/3\") - KNumber(\"2/3\")"),
174                 KNumber(QStringLiteral("5/3")) - KNumber(QStringLiteral("2/3")),
175                 QStringLiteral("1"),
176                 KNumber::TYPE_INTEGER);
177     checkResult(QStringLiteral("KNumber(\"-5/3\") - KNumber(\"4/3\")"),
178                 KNumber(QStringLiteral("-5/3")) - KNumber(QStringLiteral("4/3")),
179                 QStringLiteral("-3"),
180                 KNumber::TYPE_INTEGER);
181     checkResult(QStringLiteral("KNumber(\"5/4\") - KNumber(2.2)"), KNumber(QStringLiteral("5/4")) - KNumber(2.2), QStringLiteral("-0.95"), KNumber::TYPE_FLOAT);
182 
183     checkResult(QStringLiteral("KNumber(5.3) - KNumber(2)"), KNumber(5.3) - KNumber(2), QStringLiteral("3.3"), KNumber::TYPE_FLOAT);
184     checkResult(QStringLiteral("KNumber(5.3) - KNumber(\"3/4\")"), KNumber(5.3) - KNumber(QStringLiteral("3/4")), QStringLiteral("4.55"), KNumber::TYPE_FLOAT);
185     checkResult(QStringLiteral("KNumber(5.3) - KNumber(2.3)"), KNumber(5.3) - KNumber(2.3), QStringLiteral("3"), KNumber::TYPE_INTEGER);
186 }
187 
testingSpecial()188 void testingSpecial()
189 {
190     std::cout << "\n\n";
191     std::cout << "Testing special functions:\n";
192     std::cout << "--------------------------\n";
193 
194     checkResult(QStringLiteral("log10(KNumber(5))"), log10(KNumber(5)), QStringLiteral("0.698970004336"), KNumber::TYPE_FLOAT);
195     checkResult(QStringLiteral("log10(pow(KNumber(10), KNumber(308)))"), log10(pow(KNumber(10), KNumber(308))), QStringLiteral("308"), KNumber::TYPE_INTEGER);
196 
197     // TODO: enable this check once MPFR is commonly enabled
198     // checkResult(QStringLiteral("log10(pow(KNumber(10), KNumber(309)))"), log10(pow(KNumber(10), KNumber(309))), QLatin1String("309"), KNumber::TYPE_INTEGER);
199 
200     checkResult(QStringLiteral("exp(KNumber(4.34))"), exp(KNumber(4.34)), QStringLiteral("76.7075393383"), KNumber::TYPE_FLOAT);
201 }
202 
testingTrig()203 void testingTrig()
204 {
205     std::cout << "\n\n";
206     std::cout << "Testing trig functions:\n";
207     std::cout << "-----------------------\n";
208 
209     checkResult(QStringLiteral("sin(KNumber(5))"), sin(KNumber(5)), QStringLiteral("-0.958924274663"), KNumber::TYPE_FLOAT);
210     checkResult(QStringLiteral("cos(KNumber(5))"), cos(KNumber(5)), QStringLiteral("0.283662185463"), KNumber::TYPE_FLOAT);
211     checkResult(QStringLiteral("tan(KNumber(5))"), tan(KNumber(5)), QStringLiteral("-3.38051500625"), KNumber::TYPE_FLOAT);
212     checkResult(QStringLiteral("sin(KNumber(-5))"), sin(KNumber(-5)), QStringLiteral("0.958924274663"), KNumber::TYPE_FLOAT);
213     checkResult(QStringLiteral("cos(KNumber(-5))"), cos(KNumber(-5)), QStringLiteral("0.283662185463"), KNumber::TYPE_FLOAT);
214     checkResult(QStringLiteral("tan(KNumber(-5))"), tan(KNumber(-5)), QStringLiteral("3.38051500625"), KNumber::TYPE_FLOAT);
215 
216     checkResult(QStringLiteral("sin(KNumber(\"5/2\"))"), sin(KNumber(QStringLiteral("5/2"))), QStringLiteral("0.598472144104"), KNumber::TYPE_FLOAT);
217     checkResult(QStringLiteral("cos(KNumber(\"5/2\"))"), cos(KNumber(QStringLiteral("5/2"))), QStringLiteral("-0.801143615547"), KNumber::TYPE_FLOAT);
218     checkResult(QStringLiteral("tan(KNumber(\"5/2\"))"), tan(KNumber(QStringLiteral("5/2"))), QStringLiteral("-0.747022297239"), KNumber::TYPE_FLOAT);
219     checkResult(QStringLiteral("sin(KNumber(\"-5/2\"))"), sin(KNumber(QStringLiteral("-5/2"))), QStringLiteral("-0.598472144104"), KNumber::TYPE_FLOAT);
220     checkResult(QStringLiteral("cos(KNumber(\"-5/2\"))"), cos(KNumber(QStringLiteral("-5/2"))), QStringLiteral("-0.801143615547"), KNumber::TYPE_FLOAT);
221     checkResult(QStringLiteral("tan(KNumber(\"-5/2\"))"), tan(KNumber(QStringLiteral("-5/2"))), QStringLiteral("0.747022297239"), KNumber::TYPE_FLOAT);
222 
223     checkResult(QStringLiteral("sin(KNumber(5.3))"), sin(KNumber(5.3)), QStringLiteral("-0.832267442224"), KNumber::TYPE_FLOAT);
224     checkResult(QStringLiteral("cos(KNumber(5.3))"), cos(KNumber(5.3)), QStringLiteral("0.554374336179"), KNumber::TYPE_FLOAT);
225     checkResult(QStringLiteral("tan(KNumber(5.3))"), tan(KNumber(5.3)), QStringLiteral("-1.50127339581"), KNumber::TYPE_FLOAT);
226     checkResult(QStringLiteral("sin(KNumber(-5.3))"), sin(KNumber(-5.3)), QStringLiteral("0.832267442224"), KNumber::TYPE_FLOAT);
227     checkResult(QStringLiteral("cos(KNumber(-5.3))"), cos(KNumber(-5.3)), QStringLiteral("0.554374336179"), KNumber::TYPE_FLOAT);
228     checkResult(QStringLiteral("tan(KNumber(-5.3))"), tan(KNumber(-5.3)), QStringLiteral("1.50127339581"), KNumber::TYPE_FLOAT);
229 
230     checkResult(QStringLiteral("asin(KNumber(5))"), asin(KNumber(5)), QStringLiteral("nan"), KNumber::TYPE_ERROR);
231     checkResult(QStringLiteral("acos(KNumber(5))"), acos(KNumber(5)), QStringLiteral("nan"), KNumber::TYPE_ERROR);
232     checkResult(QStringLiteral("atan(KNumber(5))"), atan(KNumber(5)), QStringLiteral("1.37340076695"), KNumber::TYPE_FLOAT);
233     checkResult(QStringLiteral("asin(KNumber(-5))"), asin(KNumber(-5)), QStringLiteral("nan"), KNumber::TYPE_ERROR);
234     checkResult(QStringLiteral("acos(KNumber(-5))"), acos(KNumber(-5)), QStringLiteral("nan"), KNumber::TYPE_ERROR);
235     checkResult(QStringLiteral("atan(KNumber(-5))"), atan(KNumber(-5)), QStringLiteral("-1.37340076695"), KNumber::TYPE_FLOAT);
236 
237     checkResult(QStringLiteral("asin(KNumber(\"5/2\"))"), asin(KNumber(QStringLiteral("5/2"))), QStringLiteral("nan"), KNumber::TYPE_ERROR);
238     checkResult(QStringLiteral("acos(KNumber(\"5/2\"))"), acos(KNumber(QStringLiteral("5/2"))), QStringLiteral("nan"), KNumber::TYPE_ERROR);
239     checkResult(QStringLiteral("atan(KNumber(\"5/2\"))"), atan(KNumber(QStringLiteral("5/2"))), QStringLiteral("1.19028994968"), KNumber::TYPE_FLOAT);
240     checkResult(QStringLiteral("asin(KNumber(\"-5/2\"))"), asin(KNumber(QStringLiteral("-5/2"))), QStringLiteral("nan"), KNumber::TYPE_ERROR);
241     checkResult(QStringLiteral("acos(KNumber(\"-5/2\"))"), acos(KNumber(QStringLiteral("-5/2"))), QStringLiteral("nan"), KNumber::TYPE_ERROR);
242     checkResult(QStringLiteral("atan(KNumber(\"-5/2\"))"), atan(KNumber(QStringLiteral("-5/2"))), QStringLiteral("-1.19028994968"), KNumber::TYPE_FLOAT);
243 
244     checkResult(QStringLiteral("asin(KNumber(5.3))"), asin(KNumber(5.3)), QStringLiteral("nan"), KNumber::TYPE_ERROR);
245     checkResult(QStringLiteral("acos(KNumber(5.3))"), acos(KNumber(5.3)), QStringLiteral("nan"), KNumber::TYPE_ERROR);
246     checkResult(QStringLiteral("atan(KNumber(5.3))"), atan(KNumber(5.3)), QStringLiteral("1.38430942513"), KNumber::TYPE_FLOAT);
247     checkResult(QStringLiteral("asin(KNumber(-5.3))"), asin(KNumber(-5.3)), QStringLiteral("nan"), KNumber::TYPE_ERROR);
248     checkResult(QStringLiteral("acos(KNumber(-5.3))"), acos(KNumber(-5.3)), QStringLiteral("nan"), KNumber::TYPE_ERROR);
249     checkResult(QStringLiteral("atan(KNumber(-5.3))"), atan(KNumber(-5.3)), QStringLiteral("-1.38430942513"), KNumber::TYPE_FLOAT);
250 
251     checkResult(QStringLiteral("asin(KNumber(\"2/5\"))"), asin(KNumber(QStringLiteral("2/5"))), QStringLiteral("0.411516846067"), KNumber::TYPE_FLOAT);
252     checkResult(QStringLiteral("acos(KNumber(\"2/5\"))"), acos(KNumber(QStringLiteral("2/5"))), QStringLiteral("1.15927948073"), KNumber::TYPE_FLOAT);
253     checkResult(QStringLiteral("atan(KNumber(\"2/5\"))"), atan(KNumber(QStringLiteral("2/5"))), QStringLiteral("0.380506377112"), KNumber::TYPE_FLOAT);
254     checkResult(QStringLiteral("asin(KNumber(\"-2/5\"))"), asin(KNumber(QStringLiteral("-2/5"))), QStringLiteral("-0.411516846067"), KNumber::TYPE_FLOAT);
255     checkResult(QStringLiteral("acos(KNumber(\"-2/5\"))"), acos(KNumber(QStringLiteral("-2/5"))), QStringLiteral("1.98231317286"), KNumber::TYPE_FLOAT);
256     checkResult(QStringLiteral("atan(KNumber(\"-2/5\"))"), atan(KNumber(QStringLiteral("-2/5"))), QStringLiteral("-0.380506377112"), KNumber::TYPE_FLOAT);
257 
258     checkResult(QStringLiteral("asin(KNumber(0.3))"), asin(KNumber(0.3)), QStringLiteral("0.304692654015"), KNumber::TYPE_FLOAT);
259     checkResult(QStringLiteral("acos(KNumber(0.3))"), acos(KNumber(0.3)), QStringLiteral("1.26610367278"), KNumber::TYPE_FLOAT);
260     checkResult(QStringLiteral("atan(KNumber(0.3))"), atan(KNumber(0.3)), QStringLiteral("0.291456794478"), KNumber::TYPE_FLOAT);
261     checkResult(QStringLiteral("asin(KNumber(-0.3))"), asin(KNumber(-0.3)), QStringLiteral("-0.304692654015"), KNumber::TYPE_FLOAT);
262     checkResult(QStringLiteral("acos(KNumber(-0.3))"), acos(KNumber(-0.3)), QStringLiteral("1.87548898081"), KNumber::TYPE_FLOAT);
263     checkResult(QStringLiteral("atan(KNumber(-0.3))"), atan(KNumber(-0.3)), QStringLiteral("-0.291456794478"), KNumber::TYPE_FLOAT);
264 }
265 
testingMultiplications()266 void testingMultiplications()
267 {
268     std::cout << "\n\n";
269     std::cout << "Testing multiplications:\n";
270     std::cout << "------------------------\n";
271 
272     checkResult(QStringLiteral("KNumber(5) * KNumber(2)"), KNumber(5) * KNumber(2), QStringLiteral("10"), KNumber::TYPE_INTEGER);
273     checkResult(QStringLiteral("KNumber(5) * KNumber(\"2/3\")"), KNumber(5) * KNumber(QStringLiteral("2/3")), QStringLiteral("10/3"), KNumber::TYPE_FRACTION);
274     checkResult(QStringLiteral("KNumber(5) * KNumber(\"2/5\")"), KNumber(5) * KNumber(QStringLiteral("2/5")), QStringLiteral("2"), KNumber::TYPE_INTEGER);
275     checkResult(QStringLiteral("KNumber(5) * KNumber(2.3)"), KNumber(5) * KNumber(2.3), QStringLiteral("11.5"), KNumber::TYPE_FLOAT);
276     checkResult(QStringLiteral("KNumber(0) * KNumber(\"2/5\")"), KNumber(0) * KNumber(QStringLiteral("2/5")), QStringLiteral("0"), KNumber::TYPE_INTEGER);
277     checkResult(QStringLiteral("KNumber(0) * KNumber(2.3)"), KNumber(0) * KNumber(2.3), QStringLiteral("0"), KNumber::TYPE_INTEGER);
278 
279     checkResult(QStringLiteral("KNumber(\"5/3\") * KNumber(2)"), KNumber(QStringLiteral("5/3")) * KNumber(2), QStringLiteral("10/3"), KNumber::TYPE_FRACTION);
280     checkResult(QStringLiteral("KNumber(\"5/3\") * KNumber(0)"), KNumber(QStringLiteral("5/3")) * KNumber(0), QStringLiteral("0"), KNumber::TYPE_INTEGER);
281     checkResult(QStringLiteral("KNumber(\"5/3\") * KNumber(\"2/3\")"),
282                 KNumber(QStringLiteral("5/3")) * KNumber(QStringLiteral("2/3")),
283                 QStringLiteral("10/9"),
284                 KNumber::TYPE_FRACTION);
285     checkResult(QStringLiteral("KNumber(\"25/6\") * KNumber(\"12/5\")"),
286                 KNumber(QStringLiteral("25/6")) * KNumber(QStringLiteral("12/5")),
287                 QStringLiteral("10"),
288                 KNumber::TYPE_INTEGER);
289     checkResult(QStringLiteral("KNumber(\"5/2\") * KNumber(2.3)"), KNumber(QStringLiteral("5/2")) * KNumber(2.3), QStringLiteral("5.75"), KNumber::TYPE_FLOAT);
290 
291     checkResult(QStringLiteral("KNumber(5.3) * KNumber(2)"), KNumber(5.3) * KNumber(2), QStringLiteral("10.6"), KNumber::TYPE_FLOAT);
292     checkResult(QStringLiteral("KNumber(5.3) * KNumber(0)"), KNumber(5.3) * KNumber(0), QStringLiteral("0"), KNumber::TYPE_INTEGER);
293     checkResult(QStringLiteral("KNumber(5.3) * KNumber(\"1/2\")"), KNumber(5.3) * KNumber(QStringLiteral("1/2")), QStringLiteral("2.65"), KNumber::TYPE_FLOAT);
294     checkResult(QStringLiteral("KNumber(5.3) * KNumber(2.3)"), KNumber(5.3) * KNumber(2.3), QStringLiteral("12.19"), KNumber::TYPE_FLOAT);
295 }
296 
testingDivisions()297 void testingDivisions()
298 {
299     std::cout << "\n\n";
300     std::cout << "Testing divisions:\n";
301     std::cout << "------------------\n";
302 
303     checkResult(QStringLiteral("KNumber(5) / KNumber(2)"), KNumber(5) / KNumber(2), QStringLiteral("5/2"), KNumber::TYPE_FRACTION);
304     checkResult(QStringLiteral("KNumber(122) / KNumber(2)"), KNumber(122) / KNumber(2), QStringLiteral("61"), KNumber::TYPE_INTEGER);
305     checkResult(QStringLiteral("KNumber(12) / KNumber(0)"), KNumber(12) / KNumber(0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
306     checkResult(QStringLiteral("KNumber(-12) / KNumber(0)"), KNumber(-12) / KNumber(0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
307     checkResult(QStringLiteral("KNumber(5) / KNumber(\"2/3\")"), KNumber(5) / KNumber(QStringLiteral("2/3")), QStringLiteral("15/2"), KNumber::TYPE_FRACTION);
308     checkResult(QStringLiteral("KNumber(6) / KNumber(\"2/3\")"), KNumber(6) / KNumber(QStringLiteral("2/3")), QStringLiteral("9"), KNumber::TYPE_INTEGER);
309     checkResult(QStringLiteral("KNumber(5) / KNumber(2.5)"), KNumber(5) / KNumber(2.5), QStringLiteral("2"), KNumber::TYPE_INTEGER);
310     checkResult(QStringLiteral("KNumber(5) / KNumber(0.0)"), KNumber(5) / KNumber(0.0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
311     checkResult(QStringLiteral("KNumber(-5) / KNumber(0.0)"), KNumber(-5) / KNumber(0.0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
312 
313     checkResult(QStringLiteral("KNumber(\"5/3\") / KNumber(2)"), KNumber(QStringLiteral("5/3")) / KNumber(2), QStringLiteral("5/6"), KNumber::TYPE_FRACTION);
314     checkResult(QStringLiteral("KNumber(\"5/3\") / KNumber(0)"), KNumber(QStringLiteral("5/3")) / KNumber(0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
315     checkResult(QStringLiteral("KNumber(\"-5/3\") / KNumber(0)"), KNumber(QStringLiteral("-5/3")) / KNumber(0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
316     checkResult(QStringLiteral("KNumber(\"5/3\") / KNumber(\"2/3\")"),
317                 KNumber(QStringLiteral("5/3")) / KNumber(QStringLiteral("2/3")),
318                 QStringLiteral("5/2"),
319                 KNumber::TYPE_FRACTION);
320     checkResult(QStringLiteral("KNumber(\"49/3\") / KNumber(\"7/9\")"),
321                 KNumber(QStringLiteral("49/3")) / KNumber(QStringLiteral("7/9")),
322                 QStringLiteral("21"),
323                 KNumber::TYPE_INTEGER);
324     checkResult(QStringLiteral("KNumber(\"5/2\") / KNumber(2.5)"), KNumber(QStringLiteral("5/2")) / KNumber(2.5), QStringLiteral("1"), KNumber::TYPE_INTEGER);
325     checkResult(QStringLiteral("KNumber(\"5/2\") / KNumber(0.0)"), KNumber(QStringLiteral("5/2")) / KNumber(0.0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
326     checkResult(QStringLiteral("KNumber(\"-5/2\") / KNumber(0.0)"), KNumber(QStringLiteral("-5/2")) / KNumber(0.0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
327 
328     checkResult(QStringLiteral("KNumber(5.3) / KNumber(2)"), KNumber(5.3) / KNumber(2), QStringLiteral("2.65"), KNumber::TYPE_FLOAT);
329     checkResult(QStringLiteral("KNumber(5.3) / KNumber(0)"), KNumber(5.3) / KNumber(0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
330     checkResult(QStringLiteral("KNumber(-5.3) / KNumber(0)"), KNumber(-5.3) / KNumber(0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
331     checkResult(QStringLiteral("KNumber(5.3) / KNumber(\"2/3\")"), KNumber(5.3) / KNumber(QStringLiteral("2/3")), QStringLiteral("7.95"), KNumber::TYPE_FLOAT);
332     checkResult(QStringLiteral("KNumber(5.5) / KNumber(2.5)"), KNumber(5.5) / KNumber(2.5), QStringLiteral("2.2"), KNumber::TYPE_FLOAT);
333     checkResult(QStringLiteral("KNumber(5.5) / KNumber(0.0)"), KNumber(5.5) / KNumber(0.0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
334     checkResult(QStringLiteral("KNumber(-5.5) / KNumber(0.0)"), KNumber(-5.5) / KNumber(0.0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
335 }
336 
testingModulus()337 void testingModulus()
338 {
339     std::cout << "\n\n";
340     std::cout << "Testing modulus:\n";
341     std::cout << "----------------\n";
342 
343     checkResult(QStringLiteral("KNumber(23) % KNumber(4)"), KNumber(23) % KNumber(4), QStringLiteral("3"), KNumber::TYPE_INTEGER);
344     checkResult(QStringLiteral("KNumber(12) % KNumber(-5)"), KNumber(12) % KNumber(-5), QStringLiteral("2"), KNumber::TYPE_INTEGER);
345     checkResult(QStringLiteral("KNumber(-12) % KNumber(5)"), KNumber(-12) % KNumber(5), QStringLiteral("3"), KNumber::TYPE_INTEGER);
346     checkResult(QStringLiteral("KNumber(12) % KNumber(0)"), KNumber(-12) % KNumber(0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
347     checkResult(QStringLiteral("KNumber(-12) % KNumber(0)"), KNumber(-12) % KNumber(0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
348 
349 #ifdef __GNUC__
350 #warning test for other types
351 #endif
352 }
353 
testingAndOr()354 void testingAndOr()
355 {
356     std::cout << "\n\n";
357     std::cout << "Testing And/Or:\n";
358     std::cout << "---------------\n";
359 
360     checkResult(QStringLiteral("KNumber(17) & KNumber(9)"), KNumber(17) & KNumber(9), QStringLiteral("1"), KNumber::TYPE_INTEGER);
361     checkResult(QStringLiteral("KNumber(17) | KNumber(9)"), KNumber(17) | KNumber(9), QStringLiteral("25"), KNumber::TYPE_INTEGER);
362     checkResult(QStringLiteral("KNumber(1023) & KNumber(255)"), KNumber(1023) & KNumber(255), QStringLiteral("255"), KNumber::TYPE_INTEGER);
363     checkResult(QStringLiteral("KNumber(1023) | KNumber(255)"), KNumber(1023) | KNumber(255), QStringLiteral("1023"), KNumber::TYPE_INTEGER);
364 
365 #ifdef __GNUC__
366 #warning test for other types
367 #endif
368 }
369 
testingAbs()370 void testingAbs()
371 {
372     std::cout << "\n\n";
373     std::cout << "Testing absolute value:\n";
374     std::cout << "-----------------------\n";
375 
376     checkResult(QStringLiteral("KNumber(5).abs()"), KNumber(5).abs(), QStringLiteral("5"), KNumber::TYPE_INTEGER);
377     checkResult(QStringLiteral("KNumber(\"2/3\").abs()"), KNumber(QStringLiteral("2/3")).abs(), QStringLiteral("2/3"), KNumber::TYPE_FRACTION);
378     checkResult(QStringLiteral("KNumber(\"2.3\").abs()"), KNumber(QStringLiteral("2.3")).abs(), QStringLiteral("2.3"), KNumber::TYPE_FLOAT);
379 
380     checkResult(QStringLiteral("KNumber(-5).abs()"), KNumber(-5).abs(), QStringLiteral("5"), KNumber::TYPE_INTEGER);
381     checkResult(QStringLiteral("KNumber(\"-2/3\").abs()"), KNumber(QStringLiteral("-2/3")).abs(), QStringLiteral("2/3"), KNumber::TYPE_FRACTION);
382     checkResult(QStringLiteral("KNumber(\"-2.3\").abs()"), KNumber(QStringLiteral("-2.3")).abs(), QStringLiteral("2.3"), KNumber::TYPE_FLOAT);
383 }
384 
testingTruncateToInteger()385 void testingTruncateToInteger()
386 {
387     std::cout << "\n\n";
388     std::cout << "Testing truncate to an integer:\n";
389     std::cout << "-------------------------------\n";
390 
391     checkResult(QStringLiteral("KNumber(16).integerPart()"), KNumber(16).integerPart(), QStringLiteral("16"), KNumber::TYPE_INTEGER);
392     checkResult(QStringLiteral("KNumber(\"43/9\").integerPart()"), KNumber(QStringLiteral("43/9")).integerPart(), QStringLiteral("4"), KNumber::TYPE_INTEGER);
393     checkResult(QStringLiteral("KNumber(\"-43/9\").integerPart()"),
394                 KNumber(QStringLiteral("-43/9")).integerPart(),
395                 QStringLiteral("-4"),
396                 KNumber::TYPE_INTEGER);
397     checkResult(QStringLiteral("KNumber(\"5.25\").integerPart()"), KNumber(QStringLiteral("5.25")).integerPart(), QStringLiteral("5"), KNumber::TYPE_INTEGER);
398     checkResult(QStringLiteral("KNumber(\"-5.25\").integerPart()"),
399                 KNumber(QStringLiteral("-5.25")).integerPart(),
400                 QStringLiteral("-5"),
401                 KNumber::TYPE_INTEGER);
402 }
403 
testingSqrt()404 void testingSqrt()
405 {
406     std::cout << "\n\n";
407     std::cout << "Testing square root, cubic root:\n";
408     std::cout << "--------------------------------\n";
409 
410     checkResult(QStringLiteral("KNumber(16).sqrt()"), KNumber(16).sqrt(), QStringLiteral("4"), KNumber::TYPE_INTEGER);
411     checkResult(QStringLiteral("KNumber(-16).sqrt()"), KNumber(-16).sqrt(), QStringLiteral("nan"), KNumber::TYPE_ERROR);
412     checkResult(QStringLiteral("KNumber(\"16/9\").sqrt()"), KNumber(QStringLiteral("16/9")).sqrt(), QStringLiteral("4/3"), KNumber::TYPE_FRACTION);
413     checkResult(QStringLiteral("KNumber(\"-16/9\").sqrt()"), KNumber(QStringLiteral("-16/9")).sqrt(), QStringLiteral("nan"), KNumber::TYPE_ERROR);
414     checkResult(QStringLiteral("KNumber(2).sqrt()"), KNumber(2).sqrt(), QStringLiteral("1.41421356237"), KNumber::TYPE_FLOAT);
415     checkResult(QStringLiteral("KNumber(\"2/3\").sqrt()"), KNumber(QStringLiteral("2/3")).sqrt(), QStringLiteral("0.816496580928"), KNumber::TYPE_FLOAT);
416     checkResult(QStringLiteral("KNumber(\"0.25\").sqrt()"), KNumber(QStringLiteral("0.25")).sqrt(), QStringLiteral("0.5"), KNumber::TYPE_FLOAT);
417     checkResult(QStringLiteral("KNumber(\"-0.25\").sqrt()"), KNumber(QStringLiteral("-0.25")).sqrt(), QStringLiteral("nan"), KNumber::TYPE_ERROR);
418 
419     checkResult(QStringLiteral("KNumber(27).cbrt()"), KNumber(27).cbrt(), QStringLiteral("3"), KNumber::TYPE_INTEGER);
420     checkResult(QStringLiteral("KNumber(-27).cbrt()"), KNumber(-27).cbrt(), QStringLiteral("-3"), KNumber::TYPE_INTEGER);
421     checkResult(QStringLiteral("KNumber(\"27/8\").cbrt()"), KNumber(QStringLiteral("27/8")).cbrt(), QStringLiteral("3/2"), KNumber::TYPE_FRACTION);
422     checkResult(QStringLiteral("KNumber(\"-8/27\").cbrt()"), KNumber(QStringLiteral("-8/27")).cbrt(), QStringLiteral("-2/3"), KNumber::TYPE_FRACTION);
423 #ifdef __GNUC__
424 #warning need to check non-perfect cube roots
425 #endif
426     checkResult(QStringLiteral("KNumber(2).cbrt()"), KNumber(2).cbrt(), QStringLiteral("1.25992104989"), KNumber::TYPE_FLOAT);
427     checkResult(QStringLiteral("KNumber(\"2/3\").cbrt()"), KNumber(QStringLiteral("2/3")).cbrt(), QStringLiteral("0.873580464736"), KNumber::TYPE_FLOAT);
428     checkResult(QStringLiteral("KNumber(\"0.25\").cbrt()"), KNumber(QStringLiteral("0.25")).cbrt(), QStringLiteral("0.629960524947"), KNumber::TYPE_FLOAT);
429     checkResult(QStringLiteral("KNumber(\"-0.25\").cbrt()"), KNumber(QStringLiteral("-0.25")).cbrt(), QStringLiteral("-0.629960524947"), KNumber::TYPE_FLOAT);
430 }
431 
testingFactorial()432 void testingFactorial()
433 {
434     std::cout << "\n\n";
435     std::cout << "Testing factorial:\n";
436     std::cout << "------------------\n";
437 
438     checkResult(QStringLiteral("KNumber(-1).factorial()"), KNumber(-1).factorial(), QStringLiteral("nan"), KNumber::TYPE_ERROR);
439     checkResult(QStringLiteral("KNumber(-2).factorial()"), KNumber(-2).factorial(), QStringLiteral("nan"), KNumber::TYPE_ERROR);
440     checkResult(QStringLiteral("KNumber(-20).factorial()"), KNumber(-20).factorial(), QStringLiteral("nan"), KNumber::TYPE_ERROR);
441     checkResult(QStringLiteral("KNumber(-1/2).factorial()"), KNumber(QStringLiteral("-1/2")).factorial(), QStringLiteral("nan"), KNumber::TYPE_ERROR);
442     checkResult(QStringLiteral("KNumber(-0.5).factorial()"), KNumber(QStringLiteral("-0.5")).factorial(), QStringLiteral("nan"), KNumber::TYPE_ERROR);
443 
444     checkResult(QStringLiteral("KNumber(0).factorial()"), KNumber(0).factorial(), QStringLiteral("1"), KNumber::TYPE_INTEGER);
445     checkResult(QStringLiteral("KNumber(1).factorial()"), KNumber(1).factorial(), QStringLiteral("1"), KNumber::TYPE_INTEGER);
446     checkResult(QStringLiteral("KNumber(2).factorial()"), KNumber(2).factorial(), QStringLiteral("2"), KNumber::TYPE_INTEGER);
447     checkResult(QStringLiteral("KNumber(3).factorial()"), KNumber(3).factorial(), QStringLiteral("6"), KNumber::TYPE_INTEGER);
448     checkResult(QStringLiteral("KNumber(4).factorial()"), KNumber(4).factorial(), QStringLiteral("24"), KNumber::TYPE_INTEGER);
449     checkResult(QStringLiteral("KNumber(5).factorial()"), KNumber(5).factorial(), QStringLiteral("120"), KNumber::TYPE_INTEGER);
450     checkResult(QStringLiteral("KNumber(6).factorial()"), KNumber(6).factorial(), QStringLiteral("720"), KNumber::TYPE_INTEGER);
451     checkResult(QStringLiteral("KNumber(9).factorial()"), KNumber(9).factorial(), QStringLiteral("362880"), KNumber::TYPE_INTEGER);
452     checkResult(QStringLiteral("KNumber(12).factorial()"), KNumber(12).factorial(), QStringLiteral("479001600"), KNumber::TYPE_INTEGER);
453     checkResult(QStringLiteral("KNumber(13).factorial()"), KNumber(13).factorial(), QStringLiteral("6227020800"), KNumber::TYPE_INTEGER);
454 
455     checkResult(QStringLiteral("KNumber(1/2).factorial()"), KNumber(QStringLiteral("1/2")).factorial(), QStringLiteral("1"), KNumber::TYPE_INTEGER);
456     checkResult(QStringLiteral("KNumber(2/1).factorial()"), KNumber(QStringLiteral("2/1")).factorial(), QStringLiteral("2"), KNumber::TYPE_INTEGER);
457     checkResult(QStringLiteral("KNumber(3/2).factorial()"), KNumber(QStringLiteral("3/2")).factorial(), QStringLiteral("1"), KNumber::TYPE_INTEGER);
458 
459     checkResult(QStringLiteral("KNumber(0.1).factorial()"), KNumber(0.1).factorial(), QStringLiteral("1"), KNumber::TYPE_INTEGER);
460     checkResult(QStringLiteral("KNumber(0.5).factorial()"), KNumber(0.5).factorial(), QStringLiteral("1"), KNumber::TYPE_INTEGER);
461     checkResult(QStringLiteral("KNumber(1.5).factorial()"), KNumber(1.5).factorial(), QStringLiteral("1"), KNumber::TYPE_INTEGER);
462     checkResult(QStringLiteral("KNumber(2.5).factorial()"), KNumber(2.5).factorial(), QStringLiteral("2"), KNumber::TYPE_INTEGER);
463     checkResult(QStringLiteral("KNumber(3.5).factorial()"), KNumber(3.5).factorial(), QStringLiteral("6"), KNumber::TYPE_INTEGER);
464 }
465 
testingComplement()466 void testingComplement()
467 {
468     std::cout << "\n\n";
469     std::cout << "Testing complement:\n";
470     std::cout << "-------------------\n";
471 
472     // at first glance, these look like they should work
473     // but there is an annoyance. If we use the mpz_com function
474     // ~-2 == 1, but the HEX/OCT/BIN views are broken :-(
475     // specifically, if the value is negative, it goes badly pretty quick..
476 #if 0
477     checkResult(QStringLiteral("~KNumber(0)"), ~KNumber(0), QLatin1String("-1"), KNumber::TYPE_INTEGER);
478     checkResult(QStringLiteral("~KNumber(1)"), ~KNumber(1), QLatin1String("-2"), KNumber::TYPE_INTEGER);
479     checkResult(QStringLiteral("~KNumber(2)"), ~KNumber(2), QLatin1String("-3"), KNumber::TYPE_INTEGER);
480     checkResult(QStringLiteral("~KNumber(8)"), ~KNumber(8), QLatin1String("-9"), KNumber::TYPE_INTEGER);
481     checkResult(QStringLiteral("~KNumber(15)"), ~KNumber(15), QLatin1String("-16"), KNumber::TYPE_INTEGER);
482     checkResult(QStringLiteral("~KNumber(-1)"), ~KNumber(-1), QLatin1String("0"), KNumber::TYPE_INTEGER);
483     checkResult(QStringLiteral("~KNumber(-2)"), ~KNumber(-2), QLatin1String("1"), KNumber::TYPE_INTEGER);
484     checkResult(QStringLiteral("~KNumber(-3)"), ~KNumber(-3), QLatin1String("2"), KNumber::TYPE_INTEGER);
485     checkResult(QStringLiteral("~KNumber(-9)"), ~KNumber(-9), QLatin1String("8"), KNumber::TYPE_INTEGER);
486     checkResult(QStringLiteral("~KNumber(-16)"), ~KNumber(-16), QLatin1String("15"), KNumber::TYPE_INTEGER);
487 #endif
488 
489     checkResult(QStringLiteral("~KNumber(0.12345)"), ~KNumber(0.12345), QStringLiteral("nan"), KNumber::TYPE_ERROR);
490     checkResult(QStringLiteral("~KNumber(-0.12345)"), ~KNumber(-0.12345), QStringLiteral("nan"), KNumber::TYPE_ERROR);
491     checkResult(QStringLiteral("~KNumber(\"1/2\")"), ~KNumber(QStringLiteral("1/2")), QStringLiteral("nan"), KNumber::TYPE_ERROR);
492     checkResult(QStringLiteral("~KNumber(\"-1/2\")"), ~KNumber(QStringLiteral("-1/2")), QStringLiteral("nan"), KNumber::TYPE_ERROR);
493 }
494 
testingShifts()495 void testingShifts()
496 {
497     std::cout << "\n\n";
498     std::cout << "Testing left/right shift:\n";
499     std::cout << "-------------------------\n";
500 
501     checkResult(QStringLiteral("KNumber(16) << KNumber(2)"), KNumber(16) << KNumber(2), QStringLiteral("64"), KNumber::TYPE_INTEGER);
502     checkResult(QStringLiteral("KNumber(16) >> KNumber(2)"), KNumber(16) >> KNumber(2), QStringLiteral("4"), KNumber::TYPE_INTEGER);
503 }
504 
testingPower()505 void testingPower()
506 {
507     std::cout << "\n\n";
508     std::cout << "Testing Power:\n";
509     std::cout << "--------------\n";
510 
511     checkResult(QStringLiteral("KNumber(0) ^ KNumber(0)"), KNumber(0).pow(KNumber(0)), QStringLiteral("nan"), KNumber::TYPE_ERROR);
512     checkResult(QStringLiteral("KNumber(0) ^ KNumber(-4)"), KNumber(0).pow(KNumber(-4)), QStringLiteral("nan"), KNumber::TYPE_ERROR);
513     checkResult(QStringLiteral("KNumber(5) ^ KNumber(4)"), KNumber(5).pow(KNumber(4)), QStringLiteral("625"), KNumber::TYPE_INTEGER);
514     checkResult(QStringLiteral("KNumber(122) ^ KNumber(0)"), KNumber(122).pow(KNumber(0)), QStringLiteral("1"), KNumber::TYPE_INTEGER);
515     checkResult(QStringLiteral("KNumber(-5) ^ KNumber(0)"), KNumber(-5).pow(KNumber(0)), QStringLiteral("1"), KNumber::TYPE_INTEGER);
516     checkResult(QStringLiteral("KNumber(-2) ^ KNumber(3)"), KNumber(-2).pow(KNumber(3)), QStringLiteral("-8"), KNumber::TYPE_INTEGER);
517     checkResult(QStringLiteral("KNumber(-2) ^ KNumber(4)"), KNumber(-2).pow(KNumber(4)), QStringLiteral("16"), KNumber::TYPE_INTEGER);
518     checkResult(QStringLiteral("KNumber(5) ^ KNumber(-2)"), KNumber(5).pow(KNumber(-2)), QStringLiteral("1/25"), KNumber::TYPE_FRACTION);
519     checkResult(QStringLiteral("KNumber(8) ^ KNumber(\"2/3\")"), KNumber(8).pow(KNumber(QStringLiteral("2/3"))), QStringLiteral("4"), KNumber::TYPE_INTEGER);
520     checkResult(QStringLiteral("KNumber(8) ^ KNumber(\"-2/3\")"),
521                 KNumber(8).pow(KNumber(QStringLiteral("-2/3"))),
522                 QStringLiteral("1/4"),
523                 KNumber::TYPE_FRACTION);
524 
525     checkResult(QStringLiteral("KNumber(-16) ^ KNumber(\"1/4\")"),
526                 KNumber(-16).pow(KNumber(QStringLiteral("1/4"))),
527                 QStringLiteral("nan"),
528                 KNumber::TYPE_ERROR);
529     checkResult(QStringLiteral("KNumber(-8) ^ KNumber(\"1/3\")"), KNumber(-8).pow(KNumber(QStringLiteral("1/3"))), QStringLiteral("-2"), KNumber::TYPE_INTEGER);
530     checkResult(QStringLiteral("KNumber(5) ^ KNumber(0.0)"), KNumber(5).pow(KNumber(0.0)), QStringLiteral("1"), KNumber::TYPE_INTEGER);
531     checkResult(QStringLiteral("KNumber(-5) ^ KNumber(0.0)"), KNumber(-5).pow(KNumber(0.0)), QStringLiteral("1"), KNumber::TYPE_INTEGER);
532 
533     checkResult(QStringLiteral("KNumber(\"5/3\") ^ KNumber(2)"),
534                 KNumber(QStringLiteral("5/3")).pow(KNumber(2)),
535                 QStringLiteral("25/9"),
536                 KNumber::TYPE_FRACTION);
537     checkResult(QStringLiteral("KNumber(\"5/3\") ^ KNumber(0)"), KNumber(QStringLiteral("5/3")).pow(KNumber(0)), QStringLiteral("1"), KNumber::TYPE_INTEGER);
538     checkResult(QStringLiteral("KNumber(\"-5/3\") ^ KNumber(0)"), KNumber(QStringLiteral("-5/3")).pow(KNumber(0)), QStringLiteral("1"), KNumber::TYPE_INTEGER);
539     checkResult(QStringLiteral("KNumber(\"8/27\") ^ KNumber(\"2/3\")"),
540                 KNumber(QStringLiteral("8/27")).pow(KNumber(QStringLiteral("2/3"))),
541                 QStringLiteral("4/9"),
542                 KNumber::TYPE_FRACTION);
543     checkResult(QStringLiteral("KNumber(\"49/3\") ^ KNumber(\"7/9\")"),
544                 KNumber(QStringLiteral("49/3")).pow(KNumber(QStringLiteral("7/9"))),
545                 QStringLiteral("8.78016428243"),
546                 KNumber::TYPE_FLOAT);
547     checkResult(QStringLiteral("KNumber(\"5/2\") ^ KNumber(2.5)"),
548                 KNumber(QStringLiteral("5/2")).pow(KNumber(2.5)),
549                 QStringLiteral("9.88211768803"),
550                 KNumber::TYPE_FLOAT);
551     checkResult(QStringLiteral("KNumber(\"5/2\") ^ KNumber(0.0)"),
552                 KNumber(QStringLiteral("5/2")).pow(KNumber(0.0)),
553                 QStringLiteral("1"),
554                 KNumber::TYPE_INTEGER);
555     checkResult(QStringLiteral("KNumber(\"-5/2\") ^ KNumber(0.0)"),
556                 KNumber(QStringLiteral("-5/2")).pow(KNumber(0.0)),
557                 QStringLiteral("1"),
558                 KNumber::TYPE_INTEGER);
559 
560     checkResult(QStringLiteral("KNumber(5.3) ^ KNumber(2)"), KNumber(5.3).pow(KNumber(2)), QStringLiteral("28.09"), KNumber::TYPE_FLOAT);
561     checkResult(QStringLiteral("KNumber(5.3) ^ KNumber(0)"), KNumber(5.3).pow(KNumber(0)), QStringLiteral("1"), KNumber::TYPE_INTEGER);
562     checkResult(QStringLiteral("KNumber(-5.3) ^ KNumber(0)"), KNumber(-5.3).pow(KNumber(0)), QStringLiteral("1"), KNumber::TYPE_INTEGER);
563     checkResult(QStringLiteral("KNumber(5.3) ^ KNumber(\"2/3\")"),
564                 KNumber(5.3).pow(KNumber(QStringLiteral("2/3"))),
565                 QStringLiteral("3.03983898039"),
566                 KNumber::TYPE_FLOAT);
567     checkResult(QStringLiteral("KNumber(5.5) ^ KNumber(2.5)"), KNumber(5.5).pow(KNumber(2.5)), QStringLiteral("70.9425383673"), KNumber::TYPE_FLOAT);
568     checkResult(QStringLiteral("KNumber(5.5) ^ KNumber(0.0)"), KNumber(5.5).pow(KNumber(0.0)), QStringLiteral("1"), KNumber::TYPE_INTEGER);
569     checkResult(QStringLiteral("KNumber(-5.5) ^ KNumber(0.0)"), KNumber(-5.5).pow(KNumber(0.0)), QStringLiteral("1"), KNumber::TYPE_INTEGER);
570 
571     checkResult(QStringLiteral("KNumber::Pi() ^ KNumber::Pi()"), KNumber::Pi().pow(KNumber::Pi()), QStringLiteral("36.4621596072"), KNumber::TYPE_FLOAT);
572     checkResult(QStringLiteral("KNumber::Euler() ^ KNumber::Pi()"), KNumber::Euler().pow(KNumber::Pi()), QStringLiteral("23.1406926328"), KNumber::TYPE_FLOAT);
573 
574     checkResult(QStringLiteral("KNumber(2.0) ^ KNumber(0.5)"), KNumber(2.0).pow(KNumber(0.5)), QStringLiteral("1.41421356237"), KNumber::TYPE_FLOAT);
575     checkResult(QStringLiteral("KNumber(2.0) ^ KNumber(-0.5)"), KNumber(2.0).pow(KNumber(-0.5)), QStringLiteral("0.707106781187"), KNumber::TYPE_FLOAT);
576 
577     checkResult(QStringLiteral("KNumber(-2.0).exp()"), KNumber(-2.0).exp(), QStringLiteral("0.135335283237"), KNumber::TYPE_FLOAT);
578     checkResult(QStringLiteral("KNumber::Euler() ^ KNumber(-2.0)"), KNumber::Euler().pow(KNumber(-2.0)), QStringLiteral("0.135335283237"), KNumber::TYPE_FLOAT);
579 
580     checkResult(QStringLiteral("KNumber(2.0).exp()"), KNumber(2.0).exp(), QStringLiteral("7.38905609893"), KNumber::TYPE_FLOAT);
581     checkResult(QStringLiteral("KNumber::Euler() ^ KNumber(2.0)"), KNumber::Euler().pow(KNumber(2.0)), QStringLiteral("7.38905609893"), KNumber::TYPE_FLOAT);
582 
583     // TODO: kinda odd that this ends up being an integer
584     // i guess since my euler constant is only 100 digits, we've exceeded the fractional part
585     checkResult(QStringLiteral("KNumber::Euler() ^ 1000"), KNumber::Euler().pow(KNumber(1000)), QStringLiteral("1.97007111402e+434"), KNumber::TYPE_INTEGER);
586 
587     // TODO: make this test pass
588     // the problem is that it is using the libc exp function which has limits that GMP does not
589     // we should basically make this equivalent to KNumber::Euler().pow(KNumber(1000))
590     // which does work
591 #if 0
592     checkResult(QStringLiteral("KNumber(1000).exp()"), KNumber(1000).exp(), QLatin1String("23.1406926328"), KNumber::TYPE_FLOAT);
593 #endif
594 
595     KNumber::setDefaultFractionalInput(true);
596     checkResult(QStringLiteral("KNumber(\"3.1415926\") ^ KNumber(\"3.1415926\")"),
597                 KNumber(QStringLiteral("3.1415926")).pow(KNumber(QStringLiteral("3.1415926"))),
598                 QStringLiteral("36.4621554164"),
599                 KNumber::TYPE_FLOAT);
600     KNumber::setDefaultFractionalInput(false);
601 }
602 
testingInfArithmetic()603 void testingInfArithmetic()
604 {
605     std::cout << "\n\n";
606     std::cout << "Testing inf/nan-arithmetics:\n";
607     std::cout << "----------------------------\n";
608 
609     checkResult(QStringLiteral("inf + KNumber(2)"), KNumber::PosInfinity + KNumber(2), QStringLiteral("inf"), KNumber::TYPE_ERROR);
610     checkResult(QStringLiteral("KNumber(-5) + inf"), KNumber(-5) + KNumber::PosInfinity, QStringLiteral("inf"), KNumber::TYPE_ERROR);
611     checkResult(QStringLiteral("inf + KNumber(\"1/2\")"), KNumber::PosInfinity + KNumber(QStringLiteral("1/2")), QStringLiteral("inf"), KNumber::TYPE_ERROR);
612     checkResult(QStringLiteral("KNumber(\"-5/3\") + inf"), KNumber(QStringLiteral("-5/3")) + KNumber::PosInfinity, QStringLiteral("inf"), KNumber::TYPE_ERROR);
613     checkResult(QStringLiteral("inf + KNumber(2.01)"), KNumber::PosInfinity + KNumber(2.01), QStringLiteral("inf"), KNumber::TYPE_ERROR);
614     checkResult(QStringLiteral("KNumber(-5.4) + inf"), KNumber(-5.4) + KNumber::PosInfinity, QStringLiteral("inf"), KNumber::TYPE_ERROR);
615     checkResult(QStringLiteral("-inf + KNumber(2)"), KNumber::NegInfinity + KNumber(2), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
616     checkResult(QStringLiteral("KNumber(-5) + -inf"), KNumber(-5) + KNumber::NegInfinity, QStringLiteral("-inf"), KNumber::TYPE_ERROR);
617     checkResult(QStringLiteral("-inf + KNumber(\"1/2\")"), KNumber::NegInfinity + KNumber(QStringLiteral("1/2")), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
618     checkResult(QStringLiteral("KNumber(\"-5/3\") + -inf"),
619                 KNumber(QStringLiteral("-5/3")) + KNumber::NegInfinity,
620                 QStringLiteral("-inf"),
621                 KNumber::TYPE_ERROR);
622     checkResult(QStringLiteral("-inf + KNumber(2.01)"), KNumber::NegInfinity + KNumber(2.01), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
623     checkResult(QStringLiteral("KNumber(-5.4) + -inf"), KNumber(-5.4) + KNumber::NegInfinity, QStringLiteral("-inf"), KNumber::TYPE_ERROR);
624     checkResult(QStringLiteral("nan + KNumber(2)"), KNumber::NaN + KNumber(2), QStringLiteral("nan"), KNumber::TYPE_ERROR);
625     checkResult(QStringLiteral("KNumber(-5) + nan"), KNumber(-5) + KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
626     checkResult(QStringLiteral("nan + KNumber(\"1/2\")"), KNumber::NaN + KNumber(QStringLiteral("1/2")), QStringLiteral("nan"), KNumber::TYPE_ERROR);
627     checkResult(QStringLiteral("KNumber(\"-5/3\") + nan"), KNumber(QStringLiteral("-5/3")) + KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
628     checkResult(QStringLiteral("nan + KNumber(2.01)"), KNumber::NaN + KNumber(2.01), QStringLiteral("nan"), KNumber::TYPE_ERROR);
629     checkResult(QStringLiteral("KNumber(-5.4) + nan"), KNumber(-5.4) + KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
630     checkResult(QStringLiteral("inf + inf"), KNumber::PosInfinity + KNumber::PosInfinity, QStringLiteral("inf"), KNumber::TYPE_ERROR);
631     checkResult(QStringLiteral("inf + -inf"), KNumber::PosInfinity + KNumber::NegInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
632     checkResult(QStringLiteral("-inf + inf"), KNumber::NegInfinity + KNumber::PosInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
633     checkResult(QStringLiteral("-inf + -inf"), KNumber::NegInfinity + KNumber::NegInfinity, QStringLiteral("-inf"), KNumber::TYPE_ERROR);
634     checkResult(QStringLiteral("inf + nan"), KNumber::PosInfinity + KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
635     checkResult(QStringLiteral("-inf + nan"), KNumber::NegInfinity + KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
636     checkResult(QStringLiteral("nan + inf"), KNumber::NaN + KNumber::PosInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
637     checkResult(QStringLiteral("-inf + nan"), KNumber::NegInfinity + KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
638 
639     checkResult(QStringLiteral("inf - KNumber(2)"), KNumber::PosInfinity - KNumber(2), QStringLiteral("inf"), KNumber::TYPE_ERROR);
640     checkResult(QStringLiteral("KNumber(-5) - inf"), KNumber(-5) - KNumber::PosInfinity, QStringLiteral("-inf"), KNumber::TYPE_ERROR);
641     checkResult(QStringLiteral("inf - KNumber(\"1/2\")"), KNumber::PosInfinity - KNumber(QStringLiteral("1/2")), QStringLiteral("inf"), KNumber::TYPE_ERROR);
642     checkResult(QStringLiteral("KNumber(\"-5/3\") - inf"), KNumber(QStringLiteral("-5/3")) - KNumber::PosInfinity, QStringLiteral("-inf"), KNumber::TYPE_ERROR);
643     checkResult(QStringLiteral("inf - KNumber(2.01)"), KNumber::PosInfinity - KNumber(2.01), QStringLiteral("inf"), KNumber::TYPE_ERROR);
644     checkResult(QStringLiteral("KNumber(-5.4) - inf"), KNumber(-5.4) - KNumber::PosInfinity, QStringLiteral("-inf"), KNumber::TYPE_ERROR);
645     checkResult(QStringLiteral("-inf - KNumber(2)"), KNumber::NegInfinity - KNumber(2), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
646     checkResult(QStringLiteral("KNumber(-5) - -inf"), KNumber(-5) - KNumber::NegInfinity, QStringLiteral("inf"), KNumber::TYPE_ERROR);
647     checkResult(QStringLiteral("-inf - KNumber(\"1/2\")"), KNumber::NegInfinity - KNumber(QStringLiteral("1/2")), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
648     checkResult(QStringLiteral("KNumber(\"-5/3\") - -inf"), KNumber(QStringLiteral("-5/3")) - KNumber::NegInfinity, QStringLiteral("inf"), KNumber::TYPE_ERROR);
649     checkResult(QStringLiteral("-inf - KNumber(2.01)"), KNumber::NegInfinity - KNumber(2.01), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
650     checkResult(QStringLiteral("KNumber(-5.4) - -inf"), KNumber(-5.4) - KNumber::NegInfinity, QStringLiteral("inf"), KNumber::TYPE_ERROR);
651     checkResult(QStringLiteral("nan - KNumber(2)"), KNumber::NaN - KNumber(2), QStringLiteral("nan"), KNumber::TYPE_ERROR);
652     checkResult(QStringLiteral("KNumber(-5) - nan"), KNumber(-5) - KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
653     checkResult(QStringLiteral("nan - KNumber(\"1/2\")"), KNumber::NaN - KNumber(QStringLiteral("1/2")), QStringLiteral("nan"), KNumber::TYPE_ERROR);
654     checkResult(QStringLiteral("KNumber(\"-5/3\") - nan"), KNumber(QStringLiteral("-5/3")) - KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
655     checkResult(QStringLiteral("nan - KNumber(2.01)"), KNumber::NaN - KNumber(2.01), QStringLiteral("nan"), KNumber::TYPE_ERROR);
656     checkResult(QStringLiteral("KNumber(-5.4) - nan"), KNumber(-5.4) - KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
657     checkResult(QStringLiteral("inf - inf"), KNumber::PosInfinity - KNumber::PosInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
658     checkResult(QStringLiteral("inf - -inf"), KNumber::PosInfinity - KNumber::NegInfinity, QStringLiteral("inf"), KNumber::TYPE_ERROR);
659     checkResult(QStringLiteral("-inf - inf"), KNumber::NegInfinity - KNumber::PosInfinity, QStringLiteral("-inf"), KNumber::TYPE_ERROR);
660     checkResult(QStringLiteral("-inf - -inf"), KNumber::NegInfinity - KNumber::NegInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
661     checkResult(QStringLiteral("inf - nan"), KNumber::PosInfinity - KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
662     checkResult(QStringLiteral("-inf - nan"), KNumber::NegInfinity - KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
663     checkResult(QStringLiteral("nan - inf"), KNumber::NaN - KNumber::PosInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
664     checkResult(QStringLiteral("-inf - nan"), KNumber::NegInfinity - KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
665 
666     checkResult(QStringLiteral("inf * KNumber(2)"), KNumber::PosInfinity * KNumber(2), QStringLiteral("inf"), KNumber::TYPE_ERROR);
667     checkResult(QStringLiteral("KNumber(-5) * inf"), KNumber(-5) * KNumber::PosInfinity, QStringLiteral("-inf"), KNumber::TYPE_ERROR);
668     checkResult(QStringLiteral("inf * KNumber(\"1/2\")"), KNumber::PosInfinity * KNumber(QStringLiteral("1/2")), QStringLiteral("inf"), KNumber::TYPE_ERROR);
669     checkResult(QStringLiteral("KNumber(\"-5/3\") * inf"), KNumber(QStringLiteral("-5/3")) * KNumber::PosInfinity, QStringLiteral("-inf"), KNumber::TYPE_ERROR);
670     checkResult(QStringLiteral("inf * KNumber(2.01)"), KNumber::PosInfinity * KNumber(2.01), QStringLiteral("inf"), KNumber::TYPE_ERROR);
671     checkResult(QStringLiteral("KNumber(-5.4) * inf"), KNumber(-5.4) * KNumber::PosInfinity, QStringLiteral("-inf"), KNumber::TYPE_ERROR);
672     checkResult(QStringLiteral("-inf * KNumber(2)"), KNumber::NegInfinity * KNumber(2), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
673     checkResult(QStringLiteral("KNumber(-5) * -inf"), KNumber(-5) * KNumber::NegInfinity, QStringLiteral("inf"), KNumber::TYPE_ERROR);
674     checkResult(QStringLiteral("-inf * KNumber(\"1/2\")"), KNumber::NegInfinity * KNumber(QStringLiteral("1/2")), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
675     checkResult(QStringLiteral("KNumber(\"-5/3\") * -inf"), KNumber(QStringLiteral("-5/3")) * KNumber::NegInfinity, QStringLiteral("inf"), KNumber::TYPE_ERROR);
676     checkResult(QStringLiteral("-inf * KNumber(2.01)"), KNumber::NegInfinity * KNumber(2.01), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
677     checkResult(QStringLiteral("KNumber(-5.4) * -inf"), KNumber(-5.4) * KNumber::NegInfinity, QStringLiteral("inf"), KNumber::TYPE_ERROR);
678     checkResult(QStringLiteral("nan * KNumber(2)"), KNumber::NaN * KNumber(2), QStringLiteral("nan"), KNumber::TYPE_ERROR);
679     checkResult(QStringLiteral("KNumber(-5) * nan"), KNumber(-5) * KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
680     checkResult(QStringLiteral("nan * KNumber(\"1/2\")"), KNumber::NaN * KNumber(QStringLiteral("1/2")), QStringLiteral("nan"), KNumber::TYPE_ERROR);
681     checkResult(QStringLiteral("KNumber(\"-5/3\") * nan"), KNumber(QStringLiteral("-5/3")) * KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
682     checkResult(QStringLiteral("nan * KNumber(2.01)"), KNumber::NaN * KNumber(2.01), QStringLiteral("nan"), KNumber::TYPE_ERROR);
683     checkResult(QStringLiteral("KNumber(-5.4) * nan"), KNumber(-5.4) * KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
684     checkResult(QStringLiteral("inf * inf"), KNumber::PosInfinity * KNumber::PosInfinity, QStringLiteral("inf"), KNumber::TYPE_ERROR);
685     checkResult(QStringLiteral("inf * -inf"), KNumber::PosInfinity * KNumber::NegInfinity, QStringLiteral("-inf"), KNumber::TYPE_ERROR);
686     checkResult(QStringLiteral("-inf * inf"), KNumber::NegInfinity * KNumber::PosInfinity, QStringLiteral("-inf"), KNumber::TYPE_ERROR);
687     checkResult(QStringLiteral("-inf * -inf"), KNumber::NegInfinity * KNumber::NegInfinity, QStringLiteral("inf"), KNumber::TYPE_ERROR);
688     checkResult(QStringLiteral("inf * nan"), KNumber::PosInfinity * KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
689     checkResult(QStringLiteral("-inf * nan"), KNumber::NegInfinity * KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
690     checkResult(QStringLiteral("nan * inf"), KNumber::NaN * KNumber::PosInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
691     checkResult(QStringLiteral("-inf * nan"), KNumber::NegInfinity * KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
692     checkResult(QStringLiteral("KNumber(0) * inf"), KNumber(0) * KNumber::PosInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
693     checkResult(QStringLiteral("KNumber(0) * -inf"), KNumber(0) * KNumber::NegInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
694     checkResult(QStringLiteral("inf * KNumber(0)"), KNumber::PosInfinity * KNumber(0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
695     checkResult(QStringLiteral("-inf * KNumber(0)"), KNumber::NegInfinity * KNumber(0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
696     checkResult(QStringLiteral("KNumber(0.0) * inf"), KNumber(0.0) * KNumber::PosInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
697     checkResult(QStringLiteral("KNumber(0.0) * -inf"), KNumber(0.0) * KNumber::NegInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
698     checkResult(QStringLiteral("inf * KNumber(0.0)"), KNumber::PosInfinity * KNumber(0.0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
699     checkResult(QStringLiteral("-inf * KNumber(0.0)"), KNumber::NegInfinity * KNumber(0.0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
700 
701     checkResult(QStringLiteral("inf / KNumber(2)"), KNumber::PosInfinity / KNumber(2), QStringLiteral("inf"), KNumber::TYPE_ERROR);
702     checkResult(QStringLiteral("KNumber(-5) / inf"), KNumber(-5) / KNumber::PosInfinity, QStringLiteral("0"), KNumber::TYPE_INTEGER);
703     checkResult(QStringLiteral("inf / KNumber(\"1/2\")"), KNumber::PosInfinity / KNumber(QStringLiteral("1/2")), QStringLiteral("inf"), KNumber::TYPE_ERROR);
704     checkResult(QStringLiteral("KNumber(\"-5/3\") / inf"), KNumber(QStringLiteral("-5/3")) / KNumber::PosInfinity, QStringLiteral("0"), KNumber::TYPE_INTEGER);
705     checkResult(QStringLiteral("inf / KNumber(2.01)"), KNumber::PosInfinity / KNumber(2.01), QStringLiteral("inf"), KNumber::TYPE_ERROR);
706     checkResult(QStringLiteral("KNumber(-5.4) / inf"), KNumber(-5.4) / KNumber::PosInfinity, QStringLiteral("0"), KNumber::TYPE_INTEGER);
707     checkResult(QStringLiteral("-inf / KNumber(2)"), KNumber::NegInfinity / KNumber(2), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
708     checkResult(QStringLiteral("KNumber(-5) / -inf"), KNumber(-5) / KNumber::NegInfinity, QStringLiteral("0"), KNumber::TYPE_INTEGER);
709     checkResult(QStringLiteral("-inf / KNumber(\"1/2\")"), KNumber::NegInfinity / KNumber(QStringLiteral("1/2")), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
710     checkResult(QStringLiteral("KNumber(\"-5/3\") / -inf"), KNumber(QStringLiteral("-5/3")) / KNumber::NegInfinity, QStringLiteral("0"), KNumber::TYPE_INTEGER);
711     checkResult(QStringLiteral("-inf / KNumber(2.01)"), KNumber::NegInfinity / KNumber(2.01), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
712     checkResult(QStringLiteral("KNumber(-5.4) / -inf"), KNumber(-5.4) / KNumber::NegInfinity, QStringLiteral("0"), KNumber::TYPE_INTEGER);
713     checkResult(QStringLiteral("nan / KNumber(2)"), KNumber::NaN / KNumber(2), QStringLiteral("nan"), KNumber::TYPE_ERROR);
714     checkResult(QStringLiteral("KNumber(-5) / nan"), KNumber(-5) / KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
715     checkResult(QStringLiteral("nan / KNumber(\"1/2\")"), KNumber::NaN / KNumber(QStringLiteral("1/2")), QStringLiteral("nan"), KNumber::TYPE_ERROR);
716     checkResult(QStringLiteral("KNumber(\"-5/3\") / nan"), KNumber(QStringLiteral("-5/3")) / KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
717     checkResult(QStringLiteral("nan / KNumber(2.01)"), KNumber::NaN / KNumber(2.01), QStringLiteral("nan"), KNumber::TYPE_ERROR);
718     checkResult(QStringLiteral("KNumber(-5.4) / nan"), KNumber(-5.4) / KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
719     checkResult(QStringLiteral("inf / inf"), KNumber::PosInfinity / KNumber::PosInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
720     checkResult(QStringLiteral("inf / -inf"), KNumber::PosInfinity / KNumber::NegInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
721     checkResult(QStringLiteral("-inf / inf"), KNumber::NegInfinity / KNumber::PosInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
722     checkResult(QStringLiteral("-inf / -inf"), KNumber::NegInfinity / KNumber::NegInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
723     checkResult(QStringLiteral("inf / nan"), KNumber::PosInfinity / KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
724     checkResult(QStringLiteral("-inf / nan"), KNumber::NegInfinity / KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
725     checkResult(QStringLiteral("nan / inf"), KNumber::NaN / KNumber::PosInfinity, QStringLiteral("nan"), KNumber::TYPE_ERROR);
726     checkResult(QStringLiteral("-inf / nan"), KNumber::NegInfinity / KNumber::NaN, QStringLiteral("nan"), KNumber::TYPE_ERROR);
727     checkResult(QStringLiteral("KNumber(0) / inf"), KNumber(0) / KNumber::PosInfinity, QStringLiteral("0"), KNumber::TYPE_INTEGER);
728     checkResult(QStringLiteral("KNumber(0) / -inf"), KNumber(0) / KNumber::NegInfinity, QStringLiteral("0"), KNumber::TYPE_INTEGER);
729     checkResult(QStringLiteral("inf / KNumber(0)"), KNumber::PosInfinity / KNumber(0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
730     checkResult(QStringLiteral("-inf / KNumber(0)"), KNumber::NegInfinity / KNumber(0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
731     checkResult(QStringLiteral("KNumber(0.0) / inf"), KNumber(0.0) / KNumber::PosInfinity, QStringLiteral("0"), KNumber::TYPE_INTEGER);
732     checkResult(QStringLiteral("KNumber(0.0) / -inf"), KNumber(0.0) / KNumber::NegInfinity, QStringLiteral("0"), KNumber::TYPE_INTEGER);
733     checkResult(QStringLiteral("inf / KNumber(0.0)"), KNumber::PosInfinity / KNumber(0.0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
734     checkResult(QStringLiteral("-inf / KNumber(0.0)"), KNumber::NegInfinity / KNumber(0.0), QStringLiteral("nan"), KNumber::TYPE_ERROR);
735 
736     checkResult(QStringLiteral("KNumber(5) ^ KNumber(\"inf\")"), KNumber(5).pow(KNumber::PosInfinity), QStringLiteral("inf"), KNumber::TYPE_ERROR);
737     checkResult(QStringLiteral("KNumber(-5) ^ KNumber(\"inf\")"), KNumber(-5).pow(KNumber::PosInfinity), QStringLiteral("inf"), KNumber::TYPE_ERROR);
738     checkResult(QStringLiteral("KNumber(\"5/2\") ^ KNumber(\"inf\")"),
739                 KNumber(QStringLiteral("5/2")).pow(KNumber::PosInfinity),
740                 QStringLiteral("inf"),
741                 KNumber::TYPE_ERROR);
742     checkResult(QStringLiteral("KNumber(\"-5/2\") ^ KNumber(\"inf\")"),
743                 KNumber(QStringLiteral("-5/2")).pow(KNumber::PosInfinity),
744                 QStringLiteral("inf"),
745                 KNumber::TYPE_ERROR);
746     checkResult(QStringLiteral("KNumber(\"5.2\") ^ KNumber(\"inf\")"),
747                 KNumber(QStringLiteral("5.2")).pow(KNumber::PosInfinity),
748                 QStringLiteral("inf"),
749                 KNumber::TYPE_ERROR);
750     checkResult(QStringLiteral("KNumber(\"-5.2\") ^ KNumber(\"inf\")"),
751                 KNumber(QStringLiteral("-5.2")).pow(KNumber::PosInfinity),
752                 QStringLiteral("inf"),
753                 KNumber::TYPE_ERROR);
754 
755     checkResult(QStringLiteral("KNumber(5) ^ KNumber(\"-inf\")"), KNumber(5).pow(KNumber::NegInfinity), QStringLiteral("0"), KNumber::TYPE_INTEGER);
756     checkResult(QStringLiteral("KNumber(-5) ^ KNumber(\"-inf\")"), KNumber(-5).pow(KNumber::NegInfinity), QStringLiteral("0"), KNumber::TYPE_INTEGER);
757     checkResult(QStringLiteral("KNumber(\"5/2\") ^ KNumber(\"-inf\")"),
758                 KNumber(QStringLiteral("5/2")).pow(KNumber::NegInfinity),
759                 QStringLiteral("0"),
760                 KNumber::TYPE_INTEGER);
761     checkResult(QStringLiteral("KNumber(\"-5/2\") ^ KNumber(\"-inf\")"),
762                 KNumber(QStringLiteral("-5/2")).pow(KNumber::NegInfinity),
763                 QStringLiteral("0"),
764                 KNumber::TYPE_INTEGER);
765     checkResult(QStringLiteral("KNumber(\"5.2\") ^ KNumber(\"-inf\")"),
766                 KNumber(QStringLiteral("5.2")).pow(KNumber::NegInfinity),
767                 QStringLiteral("0"),
768                 KNumber::TYPE_INTEGER);
769     checkResult(QStringLiteral("KNumber(\"-5.2\") ^ KNumber(\"-inf\")"),
770                 KNumber(QStringLiteral("-5.2")).pow(KNumber::NegInfinity),
771                 QStringLiteral("0"),
772                 KNumber::TYPE_INTEGER);
773 
774     checkResult(QStringLiteral("KNumber(5) ^ KNumber(\"nan\")"), KNumber(5).pow(KNumber::NaN), QStringLiteral("nan"), KNumber::TYPE_ERROR);
775     checkResult(QStringLiteral("KNumber(-5) ^ KNumber(\"nan\")"), KNumber(-5).pow(KNumber::NaN), QStringLiteral("nan"), KNumber::TYPE_ERROR);
776     checkResult(QStringLiteral("KNumber(\"5/2\") ^ KNumber(\"nan\")"),
777                 KNumber(QStringLiteral("5/2")).pow(KNumber::NaN),
778                 QStringLiteral("nan"),
779                 KNumber::TYPE_ERROR);
780     checkResult(QStringLiteral("KNumber(\"-5/2\") ^ KNumber(\"nan\")"),
781                 KNumber(QStringLiteral("-5/2")).pow(KNumber::NaN),
782                 QStringLiteral("nan"),
783                 KNumber::TYPE_ERROR);
784     checkResult(QStringLiteral("KNumber(\"5.2\") ^ KNumber(\"nan\")"),
785                 KNumber(QStringLiteral("5.2")).pow(KNumber::NaN),
786                 QStringLiteral("nan"),
787                 KNumber::TYPE_ERROR);
788     checkResult(QStringLiteral("KNumber(\"-5.2\") ^ KNumber(\"nan\")"),
789                 KNumber(QStringLiteral("-5.2")).pow(KNumber::NaN),
790                 QStringLiteral("nan"),
791                 KNumber::TYPE_ERROR);
792 
793     checkResult(QStringLiteral("KNumber(\"nan\") ^ KNumber(\"nan\")"), KNumber::NaN.pow(KNumber::NaN), QStringLiteral("nan"), KNumber::TYPE_ERROR);
794     checkResult(QStringLiteral("KNumber(\"nan\") ^ KNumber(\"inf\")"), KNumber::NaN.pow(KNumber::PosInfinity), QStringLiteral("nan"), KNumber::TYPE_ERROR);
795     checkResult(QStringLiteral("KNumber(\"nan\") ^ KNumber(\"-inf\")"), KNumber::NaN.pow(KNumber::NegInfinity), QStringLiteral("nan"), KNumber::TYPE_ERROR);
796 
797     checkResult(QStringLiteral("KNumber(\"inf\") ^ KNumber(\"nan\")"), KNumber::PosInfinity.pow(KNumber::NaN), QStringLiteral("nan"), KNumber::TYPE_ERROR);
798     checkResult(QStringLiteral("KNumber(\"inf\") ^ KNumber(\"inf\")"),
799                 KNumber::PosInfinity.pow(KNumber::PosInfinity),
800                 QStringLiteral("inf"),
801                 KNumber::TYPE_ERROR);
802     checkResult(QStringLiteral("KNumber(\"inf\") ^ KNumber(\"-inf\")"),
803                 KNumber::PosInfinity.pow(KNumber::NegInfinity),
804                 QStringLiteral("0"),
805                 KNumber::TYPE_INTEGER);
806 
807     checkResult(QStringLiteral("KNumber(\"-inf\") ^ KNumber(\"nan\")"), KNumber::NegInfinity.pow(KNumber::NaN), QStringLiteral("nan"), KNumber::TYPE_ERROR);
808     checkResult(QStringLiteral("KNumber(\"-inf\") ^ KNumber(\"inf\")"),
809                 KNumber::NegInfinity.pow(KNumber::PosInfinity),
810                 QStringLiteral("inf"),
811                 KNumber::TYPE_ERROR);
812     checkResult(QStringLiteral("KNumber(\"-inf\") ^ KNumber(\"-inf\")"),
813                 KNumber::NegInfinity.pow(KNumber::NegInfinity),
814                 QStringLiteral("0"),
815                 KNumber::TYPE_INTEGER);
816 }
817 
testingFloatPrecision()818 void testingFloatPrecision()
819 {
820     KNumber::setDefaultFloatPrecision(100);
821     checkResult(QStringLiteral("Precision >= 100: (KNumber(1) + KNumber(\"1e-80\")) - KNumber(1)"),
822                 (KNumber(1) + KNumber(QStringLiteral("1e-80"))) - KNumber(1),
823                 QStringLiteral("1e-80"),
824                 KNumber::TYPE_FLOAT);
825     checkResult(QStringLiteral("Precision >= 100: (KNumber(1) + KNumber(\"1e-980\")) - KNumber(1)"),
826                 (KNumber(1) + KNumber(QStringLiteral("1e-980"))) - KNumber(1),
827                 QStringLiteral("0"),
828                 KNumber::TYPE_INTEGER);
829 
830     KNumber::setDefaultFloatPrecision(1000);
831     checkResult(QStringLiteral("Precision >= 1000: (KNumber(1) + KNumber(\"1e-980\")) - KNumber(1)"),
832                 (KNumber(1) + KNumber(QStringLiteral("1e-980"))) - KNumber(1),
833                 QStringLiteral("1e-980"),
834                 KNumber::TYPE_FLOAT);
835 
836     KNumber::setDefaultFloatPrecision(20);
837     checkResult(QStringLiteral("Precision >= 20: sin(KNumber(30))"),
838                 sin(KNumber(30) * (KNumber::Pi() / KNumber(180))),
839                 QStringLiteral("0.5"),
840                 KNumber::TYPE_FLOAT);
841 }
842 
testingOutput()843 void testingOutput()
844 {
845     KNumber::setDefaultFloatOutput(false);
846     checkResult(QStringLiteral("Fractional output: KNumber(\"1/4\")"), KNumber(QStringLiteral("1/4")), QStringLiteral("1/4"), KNumber::TYPE_FRACTION);
847 
848     KNumber::setDefaultFloatOutput(true);
849     checkResult(QStringLiteral("Float: KNumber(\"1/4\")"), KNumber(QStringLiteral("1/4")), QStringLiteral("0.25"), KNumber::TYPE_FRACTION);
850 
851     KNumber::setDefaultFloatOutput(false);
852     KNumber::setSplitoffIntegerForFractionOutput(true);
853     checkResult(QStringLiteral("Fractional output: KNumber(\"1/4\")"), KNumber(QStringLiteral("1/4")), QStringLiteral("1/4"), KNumber::TYPE_FRACTION);
854     checkResult(QStringLiteral("Fractional output: KNumber(\"-1/4\")"), KNumber(QStringLiteral("-1/4")), QStringLiteral("-1/4"), KNumber::TYPE_FRACTION);
855     checkResult(QStringLiteral("Fractional output: KNumber(\"21/4\")"), KNumber(QStringLiteral("21/4")), QStringLiteral("5 1/4"), KNumber::TYPE_FRACTION);
856     checkResult(QStringLiteral("Fractional output: KNumber(\"-21/4\")"), KNumber(QStringLiteral("-21/4")), QStringLiteral("-5 1/4"), KNumber::TYPE_FRACTION);
857 
858     KNumber::setSplitoffIntegerForFractionOutput(false);
859     checkResult(QStringLiteral("Fractional output: KNumber(\"1/4\")"), KNumber(QStringLiteral("1/4")), QStringLiteral("1/4"), KNumber::TYPE_FRACTION);
860     checkResult(QStringLiteral("Fractional output: KNumber(\"-1/4\")"), KNumber(QStringLiteral("-1/4")), QStringLiteral("-1/4"), KNumber::TYPE_FRACTION);
861     checkResult(QStringLiteral("Fractional output: KNumber(\"21/4\")"), KNumber(QStringLiteral("21/4")), QStringLiteral("21/4"), KNumber::TYPE_FRACTION);
862     checkResult(QStringLiteral("Fractional output: KNumber(\"-21/4\")"), KNumber(QStringLiteral("-21/4")), QStringLiteral("-21/4"), KNumber::TYPE_FRACTION);
863 }
864 
testingConstructors()865 void testingConstructors()
866 {
867     std::cout << "Testing Constructors:\n";
868     std::cout << "---------------------\n";
869 
870     checkResult(QStringLiteral("KNumber(5)"), KNumber(5), QStringLiteral("5"), KNumber::TYPE_INTEGER);
871     checkType(QStringLiteral("KNumber(5.3)"), KNumber(5.3).type(), KNumber::TYPE_FLOAT);
872     checkType(QStringLiteral("KNumber(0.0)"), KNumber(0.0).type(), KNumber::TYPE_INTEGER);
873 
874     checkResult(QStringLiteral("KNumber(\"5\")"), KNumber(QStringLiteral("5")), QStringLiteral("5"), KNumber::TYPE_INTEGER);
875     checkResult(QStringLiteral("KNumber(\"5/3\")"), KNumber(QStringLiteral("5/3")), QStringLiteral("5/3"), KNumber::TYPE_FRACTION);
876     checkResult(QStringLiteral("KNumber(\"5/1\")"), KNumber(QStringLiteral("5/1")), QStringLiteral("5"), KNumber::TYPE_INTEGER);
877     checkResult(QStringLiteral("KNumber(\"0/12\")"), KNumber(QStringLiteral("0/12")), QStringLiteral("0"), KNumber::TYPE_INTEGER);
878     KNumber::setDefaultFractionalInput(true);
879     std::cout << "Read decimals as fractions:\n";
880     checkResult(QStringLiteral("KNumber(\"5\")"), KNumber(QStringLiteral("5")), QStringLiteral("5"), KNumber::TYPE_INTEGER);
881     checkResult(QStringLiteral("KNumber(\"1.2\")"), KNumber(QStringLiteral("1.2")), QStringLiteral("6/5"), KNumber::TYPE_FRACTION);
882     checkResult(QStringLiteral("KNumber(\"-0.02\")"), KNumber(QStringLiteral("-0.02")), QStringLiteral("-1/50"), KNumber::TYPE_FRACTION);
883     checkResult(QStringLiteral("KNumber(\"5e-2\")"), KNumber(QStringLiteral("5e-2")), QStringLiteral("1/20"), KNumber::TYPE_FRACTION);
884     checkResult(QStringLiteral("KNumber(\"1.2e3\")"), KNumber(QStringLiteral("1.2e3")), QStringLiteral("1200"), KNumber::TYPE_INTEGER);
885     checkResult(QStringLiteral("KNumber(\"0.02e+1\")"), KNumber(QStringLiteral("0.02e+1")), QStringLiteral("1/5"), KNumber::TYPE_FRACTION);
886 
887     KNumber::setDefaultFractionalInput(false);
888     std::cout << "Read decimals as floats:\n";
889     checkResult(QStringLiteral("KNumber(\"5.3\")"), KNumber(QStringLiteral("5.3")), QStringLiteral("5.3"), KNumber::TYPE_FLOAT);
890 
891     checkResult(QStringLiteral("KNumber(\"nan\")"), KNumber(QStringLiteral("nan")), QStringLiteral("nan"), KNumber::TYPE_ERROR);
892     checkResult(QStringLiteral("KNumber(\"inf\")"), KNumber(QStringLiteral("inf")), QStringLiteral("inf"), KNumber::TYPE_ERROR);
893     checkResult(QStringLiteral("KNumber(\"-inf\")"), KNumber(QStringLiteral("-inf")), QStringLiteral("-inf"), KNumber::TYPE_ERROR);
894 
895     // test accepting of non-US number formatted strings
896     KNumber::setDecimalSeparator(QStringLiteral(","));
897     checkResult(QStringLiteral("KNumber(\"5,2\")"), KNumber(QStringLiteral("5,2")), QStringLiteral("5.2"), KNumber::TYPE_FLOAT);
898     KNumber::setDecimalSeparator(QStringLiteral("."));
899 }
900 
testingConstants()901 void testingConstants()
902 {
903     std::cout << "\n\n";
904     std::cout << "Constants:\n";
905     std::cout << "----------\n";
906 
907     checkType(QStringLiteral("KNumber::Zero"), KNumber::Zero.type(), KNumber::TYPE_INTEGER);
908     checkType(QStringLiteral("KNumber::One"), KNumber::One.type(), KNumber::TYPE_INTEGER);
909     checkType(QStringLiteral("KNumber::NegOne"), KNumber::NegOne.type(), KNumber::TYPE_INTEGER);
910     checkType(QStringLiteral("KNumber::Pi"), KNumber::Pi().type(), KNumber::TYPE_FLOAT);
911     checkType(QStringLiteral("KNumber::Euler"), KNumber::Euler().type(), KNumber::TYPE_FLOAT);
912 }
913 
914 }
915 
main()916 int main()
917 {
918     testingConstants();
919     testingConstructors();
920     testingCompare();
921     testingAdditions();
922     testingSubtractions();
923     testingMultiplications();
924     testingDivisions();
925     testingAndOr();
926     testingModulus();
927     testingAbs();
928     testingSqrt();
929     testingFactorial();
930     testingComplement();
931     testingPower();
932     testingTruncateToInteger();
933     testingShifts();
934     testingInfArithmetic();
935     testingFloatPrecision();
936     testingTrig();
937     testingSpecial();
938     testingOutput();
939     std::cout << "SUCCESS" << std::endl;
940 }
941