1 /* Copyright (c) 2008-2009 Robert Ancell
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 #include "mp-equation.h"
27 #include "mp-serializer.h"
28 #include "unit-manager.h"
30 static MPEquationOptions options
;
33 static int passes
= 0;
35 /* If we're not using GNU C, elide __attribute__ */
37 # define __attribute__(x) /*NOTHING*/
40 static void pass(const char *format
, ...) __attribute__((format(printf
, 1, 2)));
41 static void fail(const char *format
, ...) __attribute__((format(printf
, 1, 2)));
44 static void pass(const char *format
, ...)
49 va_start(args, format);
50 vprintf(format, args);
57 static void fail(const char *format
, ...)
62 va_start(args
, format
);
63 vprintf(format
, args
);
71 error_code_to_string(MPErrorCode error
)
73 static char error_string
[1024];
75 if (error
!= PARSER_ERR_MP
)
76 return mp_error_code_to_string(error
);
78 snprintf(error_string
, 1024, "PARSER_ERR_MP(\"%s\")", mp_get_error());
84 test(char *expression
, char *expected
, int expected_error
)
89 error
= mp_equation_parse(expression
, &options
, &result
, NULL
);
93 MpSerializer
*serializer
;
95 serializer
= mp_serializer_new(MP_DISPLAY_FORMAT_FIXED
, options
.base
, 9);
96 result_str
= mp_serializer_to_string(serializer
, &result
);
97 g_object_unref(serializer
);
99 if(expected_error
!= PARSER_ERR_NONE
)
100 fail("'%s' -> %s, expected error %s", expression
, result_str
, error_code_to_string(expected_error
));
101 else if(strcmp(result_str
, expected
) != 0)
102 fail("'%s' -> '%s', expected '%s'", expression
, result_str
, expected
);
104 pass("'%s' -> '%s'", expression
, result_str
);
108 if(error
== expected_error
)
109 pass("'%s' -> error %s", expression
, error_code_to_string(error
));
110 else if(expected_error
== PARSER_ERR_NONE
)
111 fail("'%s' -> error %s, expected result %s", expression
,
112 error_code_to_string(error
), expected
);
114 fail("'%s' -> error %s, expected error %s", expression
,
115 error_code_to_string(error
), error_code_to_string(expected_error
));
121 do_convert(const MPNumber
*x
, const char *x_units
, const char *z_units
, MPNumber
*z
, void *data
)
123 return unit_manager_convert(unit_manager_get_default(), x
, x_units
, z_units
, z
);
130 memset(&options
, 0, sizeof(options
));
132 options
.wordlen
= 32;
133 options
.angle_units
= MP_DEGREES
;
134 options
.convert
= do_convert
;
137 //test("π radians in degrees", "180", 0);
138 test("100 gradians in degrees", "90", 0);
141 test("1 meter in mm", "1000", 0);
142 test("1m in mm", "1000", 0);
143 test("1 inch in cm", "2.54", 0);
146 test("1m² in mm²", "1000000", 0);
149 test("1m³ in mm³", "1000000000", 0);
152 test("1 kg in pounds", "2.204622622", 0);
155 test("1 minute in seconds", "60", 0);
156 test("1s in ms", "1000", 0);
159 //test("100˚C in ˚F", "", 0);
160 //test("0˚C in ˚F", "32", 0);
161 //test("0˚K in ˚C", "−273.15", 0);
162 test("100degC in degF", "212", 0);
163 test("0degC in degF", "32", 0);
164 test("0degK in degC", "−273.15", 0);
169 variable_is_defined(const char *name
, void *data
)
171 return strcmp (name
, "x") == 0 || strcmp (name
, "y") == 0;
176 get_variable(const char *name
, MPNumber
*z
, void *data
)
178 if (strcmp (name
, "x") == 0) {
179 mp_set_from_integer (2, z
);
182 if (strcmp (name
, "y") == 0) {
183 mp_set_from_integer (3, z
);
191 set_variable(const char *name
, const MPNumber
*x
, void *data
)
198 memset(&options
, 0, sizeof(options
));
200 options
.wordlen
= 32;
201 options
.angle_units
= MP_DEGREES
;
202 options
.variable_is_defined
= variable_is_defined
;
203 options
.get_variable
= get_variable
;
204 options
.set_variable
= set_variable
;
207 test("2₁₀", "10", 0);
210 test("16434824₁₀", "76543210", 0);
214 test("18364758544493064720₁₀", "FEDCBA9876543210", 0);
217 test("0₂", "0", 0); test("0₈", "0", 0); test("0", "0", 0); test("0₁₆", "0", 0);
218 test("1₂", "1", 0); test("1₈", "1", 0); test("1", "1", 0); test("1₁₆", "1", 0);
219 test("2₂", "", PARSER_ERR_INVALID
); test("2₈", "2", 0); test("2", "2", 0); test("2₁₆", "2", 0);
220 test("3₂", "", PARSER_ERR_INVALID
); test("3₈", "3", 0); test("3", "3", 0); test("3₁₆", "3", 0);
221 test("4₂", "", PARSER_ERR_INVALID
); test("4₈", "4", 0); test("4", "4", 0); test("4₁₆", "4", 0);
222 test("5₂", "", PARSER_ERR_INVALID
); test("5₈", "5", 0); test("5", "5", 0); test("5₁₆", "5", 0);
223 test("6₂", "", PARSER_ERR_INVALID
); test("6₈", "6", 0); test("6", "6", 0); test("6₁₆", "6", 0);
224 test("7₂", "", PARSER_ERR_INVALID
); test("7₈", "7", 0); test("7", "7", 0); test("7₁₆", "7", 0);
225 test("8₂", "", PARSER_ERR_INVALID
); test("8₈", "", PARSER_ERR_INVALID
); test("8", "8", 0); test("8₁₆", "8", 0);
226 test("9₂", "", PARSER_ERR_INVALID
); test("9₈", "", PARSER_ERR_INVALID
); test("9", "9", 0); test("9₁₆", "9", 0);
227 test("A₂", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("A₈", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("A", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("A₁₆", "10", 0);
228 test("B₂", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("B₈", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("B", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("B₁₆", "11", 0);
229 test("C₂", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("C₈", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("C", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("C₁₆", "12", 0);
230 test("D₂", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("D₈", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("D", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("D₁₆", "13", 0);
231 test("E₂", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("E₈", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("E", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("E₁₆", "14", 0);
232 test("F₂", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("F₈", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("F", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("F₁₆", "15", 0);
233 test("a₂", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("a₈", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("a", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("a₁₆", "10", 0);
234 test("b₂", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("b₈", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("b", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("b₁₆", "11", 0);
235 test("c₂", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("c₈", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("c", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("c₁₆", "12", 0);
236 test("d₂", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("d₈", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("d", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("d₁₆", "13", 0);
237 test("e₂", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("e₈", "", PARSER_ERR_UNKNOWN_VARIABLE
); /* e is a built-in variable */ test("e₁₆", "14", 0);
238 test("f₂", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("f₈", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("f", "", PARSER_ERR_UNKNOWN_VARIABLE
); test("f₁₆", "15", 0);
242 test("+ 1", "1", 0); // FIXME: Should this be allowed?
243 test("− 1", "−1", 0); // FIXME: Should this be allowed?
244 test("++1", "1", PARSER_ERR_INVALID
);
246 test("255", "255", 0);
247 test("256", "256", 0);
249 test("1½", "1.5", 0);
252 test("0°30'", "0.5", 0);
253 //test("0°0.1'", "1", 0); // FIXME: Not yet supported
254 test("0°0'1\"", "0.000277778", 0);
255 test("0°0'0.1\"", "0.000027778", 0);
256 test("1.00", "1", 0);
257 test("1.01", "1.01", 0);
259 test("١٢٣٤٥٦٧٨٩٠", "1234567890", 0);
260 test("۱۲۳۴۵۶۷۸۹۰", "1234567890", 0);
263 //test("2A", "2000000000000000", 0);
264 test("2T", "2000000000000", 0);
265 test("2G", "2000000000", 0);
266 test("2M", "2000000", 0);
267 test("2k", "2000", 0);
268 test("2c", "0.02", 0);
269 test("2d", "0.2", 0);
270 test("2c", "0.02", 0);
271 test("2m", "0.002", 0);
272 test("2u", "0.000002", 0);
273 test("2µ", "0.000002", 0);
274 test("2n", "0.000000002", 0);
275 //test("2p", "0.000000000002", 0); // FIXME: Need to print out significant figures, not decimal places
276 //test("2f", "0.000000000000002", 0); // FIXME: Need to print out significant figures, not decimal places
277 //test("2A3", "2300000000000000", 0);
278 test("2T3", "2300000000000", 0);
279 test("2G3", "2300000000", 0);
280 test("2M3", "2300000", 0);
281 test("2k3", "2300", 0);
282 test("2c3", "0.023", 0);
283 test("2d3", "0.23", 0);
284 test("2c3", "0.023", 0);
285 test("2m3", "0.0023", 0);
286 test("2u3", "0.0000023", 0);
287 test("2µ3", "0.0000023", 0);
288 //test("2n3", "0.0000000023", 0); // FIXME: Need to print out significant figures, not decimal places
289 //test("2p3", "0.0000000000023", 0); // FIXME: Need to print out significant figures, not decimal places
290 //test("2f3", "0.0000000000000023", 0); // FIXME: Need to print out significant figures, not decimal places
293 test("2×10^3", "2000", 0);
294 test("2×10^−3", "0.002", 0);
298 test("z", "", PARSER_ERR_UNKNOWN_VARIABLE
);
300 test("y2", "", PARSER_ERR_INVALID
);
301 test("y 2", "", PARSER_ERR_INVALID
);
302 test("2z", "", PARSER_ERR_UNKNOWN_VARIABLE
);
303 test("z2", "", PARSER_ERR_UNKNOWN_VARIABLE
);
304 test("z 2", "", PARSER_ERR_UNKNOWN_VARIABLE
);
305 test("z(2)", "", PARSER_ERR_UNKNOWN_VARIABLE
);
307 test("2y²", "18", 0);
311 test("2xy", "12", 0);
312 test("x²y", "12", 0);
313 test("xy²", "18", 0);
314 test("(xy)²", "36", 0);
315 test("2x²y", "24", 0);
316 test("2xy²", "36", 0);
317 test("2x²y²", "72", 0);
318 test("x²yx²y", "144", 0);
319 test("x³+2x²−5", "11", 0);
320 test("2(x+3y)", "22", 0);
321 test("x(x+3y)", "22", 0);
322 test("(x+3y)(2x-4y)", "−88", 0);
323 test("2x²+2xy−12y²", "−88", 0);
325 test("π", "3.141592654", 0);
326 test("e", "2.718281828", 0);
328 test("z=99", "99", 0);
329 test("longname=99", "99", 0);
330 //test("e=99", "", PARSER_ERR_BUILTIN_VARIABLE);
336 test("40000+0.001", "40000.001", 0);
337 test("0.001+40000", "40000.001", 0);
338 test("2-3", "−1", 0);
339 test("2−3", "−1", 0);
341 test("40000−0.001", "39999.999", 0);
342 test("0.001−40000", "−39999.999", 0);
345 test("−2×3", "−6", 0);
346 test("2×−3", "−6", 0);
347 test("−2×−3", "6", 0);
350 test("1÷2", "0.5", 0);
351 test("−6÷3", "−2", 0);
352 test("6÷−3", "−2", 0);
353 test("−6÷−3", "2", 0);
354 test("(−3)÷(−6)", "0.5", 0);
356 test("1203÷1", "1203", 0);
357 test("−0÷32352.689", "0", 0);
358 test("1÷4", "0.25", 0);
359 test("1÷3", "0.333333333", 0);
360 test("2÷3", "0.666666667", 0);
361 test("1÷0", "", PARSER_ERR_MP
);
362 test("0÷0", "", PARSER_ERR_MP
);
365 test("1000000000000000−1000000000000000", "0", 0);
366 test("1000000000000000÷1000000000000000", "1", 0);
367 test("1000000000000000×0.000000000000001", "1", 0);
369 /* Order of operations */
370 test("1−0.9−0.1", "0", 0);
371 test("1+2×3", "7", 0);
372 test("1+(2×3)", "7", 0);
373 test("(1+2)×3", "9", 0);
374 test("(1+2×3)", "7", 0);
377 test("100%", "1", 0);
378 test("1%", "0.01", 0);
379 test("100+1%", "101", 0);
380 test("100−1%", "99", 0);
381 test("100×1%", "1", 0);
382 test("100÷1%", "10000", 0);
387 test("5!", "120", 0);
388 test("69!", "171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000", 0);
389 test("0.1!", "", PARSER_ERR_MP
);
390 test("−1!", "−1", 0);
391 test("(−1)!", "", PARSER_ERR_MP
);
392 test("−(1!)", "−1", 0);
397 test("2¹⁰", "1024", 0);
398 test("(1+2)²", "9", 0);
399 test("(x)²", "4", 0);
400 test("|1−3|²", "4", 0);
401 test("|x|²", "4", 0);
406 test("2⁻¹", "0.5", 0);
407 //test("2⁻", "", PARSER_ERR_MP); // FIXME: Maybe an error in bison?
408 test("2^−1", "0.5", 0);
409 test("2^(−1)", "0.5", 0);
410 test("x⁻¹", "0.5", 0);
411 test("−10^2", "−100", 0);
412 test("(−10)^2", "100", 0);
413 test("−(10^2)", "−100", 0);
414 test("2^100", "1267650600228229401496703205376", 0);
415 test("4^3^2", "262144", 0);
416 test("4^(3^2)", "262144", 0);
417 test("(4^3)^2", "4096", 0);
419 test("√4−2", "0", 0);
423 test("₁₀√1024", "2", 0);
424 test("√(2+2)", "2", 0);
426 test("2×√4", "4", 0);
427 test("Sqrt(4)", "2", 0);
428 test("Sqrt(2)", "1.414213562", 0);
429 test("4^0.5", "2", 0);
430 test("2^0.5", "1.414213562", 0);
431 test("₃√−8", "−2", 0);
432 test("(−8)^(1÷3)", "−2", 0);
434 test("0 mod 7", "0", 0);
435 test("6 mod 7", "6", 0);
436 test("7 mod 7", "0", 0);
437 test("8 mod 7", "1", 0);
438 test("−1 mod 7", "6", 0);
440 test("sgn 0", "0", 0);
441 test("sgn 3", "1", 0);
442 test("sgn −3", "−1", 0);
446 test("⌊−3⌋", "−3", 0);
447 test("⌈−3⌉", "−3", 0);
448 test("[−3]", "−3", 0);
449 test("⌊3.2⌋", "3", 0);
450 test("⌈3.2⌉", "4", 0);
451 test("[3.2]", "3", 0);
452 test("⌊−3.2⌋", "−4", 0);
453 test("⌈−3.2⌉", "−3", 0);
454 test("[−3.2]", "−3", 0);
455 test("⌊3.5⌋", "3", 0);
456 test("⌈3.5⌉", "4", 0);
457 test("[3.5]", "4", 0);
458 test("⌊−3.5⌋", "−4", 0);
459 test("⌈−3.5⌉", "−3", 0);
460 test("[−3.5]", "−4", 0);
461 test("⌊3.7⌋", "3", 0);
462 test("⌈3.7⌉", "4", 0);
463 test("[3.7]", "4", 0);
464 test("⌊−3.7⌋", "−4", 0);
465 test("⌈−3.7⌉", "−3", 0);
466 test("[−3.7]", "−4", 0);
467 test("{3.2}", "0.2", 0);
468 test("{−3.2}", "0.8", 0);
471 test("|−1|", "1", 0);
472 test("|3−5|", "2", 0);
474 test("abs 1", "1", 0);
475 test("abs (−1)", "1", 0);
477 test("log 0", "", PARSER_ERR_MP
);
478 test("log 1", "0", 0);
479 test("log 2", "0.301029996", 0);
480 test("log 10", "1", 0);
481 test("log₁₀ 10", "1", 0);
482 test("log₂ 2", "1", 0);
483 test("2 log 2", "0.602059991", 0);
485 test("ln 0", "", PARSER_ERR_MP
);
486 test("ln 1", "0", 0);
487 test("ln 2", "0.693147181", 0);
488 test("ln e", "1", 0);
489 test("2 ln 2", "1.386294361", 0);
491 options
.angle_units
= MP_DEGREES
;
492 test("sin 0", "0", 0);
493 test("sin 45 − 1÷√2", "0", 0);
494 test("sin 20 + sin(−20)", "0", 0);
495 test("sin 90", "1", 0);
496 test("sin 180", "0", 0);
497 test("2 sin 90", "2", 0);
498 test("sin²45", "0.5", 0);
500 test("cos 0", "1", 0);
501 test("cos 45 − 1÷√2", "0", 0);
502 test("cos 20 − cos (−20)", "0", 0);
503 test("cos 90", "0", 0);
504 test("cos 180", "−1", 0);
505 test("2 cos 0", "2", 0);
506 test("cos²45", "0.5", 0);
508 test("tan 0", "0", 0);
509 test("tan 10 − sin 10÷cos 10", "0", 0);
510 test("tan 90", "", PARSER_ERR_MP
);
511 test("tan 10", "0.176326981", 0);
512 test("tan²10", "0.031091204", 0);
514 test("cos⁻¹ 0", "90", 0);
515 test("cos⁻¹ 1", "0", 0);
516 test("cos⁻¹ (−1)", "180", 0);
517 test("cos⁻¹ (1÷√2)", "45", 0);
519 test("sin⁻¹ 0", "0", 0);
520 test("sin⁻¹ 1", "90", 0);
521 test("sin⁻¹ (−1)", "−90", 0);
522 test("sin⁻¹ (1÷√2)", "45", 0);
524 test("cosh 0", "1", 0);
525 test("cosh 10 − (e^10 + e^−10)÷2", "0", 0);
527 test("sinh 0", "0", 0);
528 test("sinh 10 − (e^10 − e^−10)÷2", "0", 0);
529 test("sinh (−10) + sinh 10", "0", 0);
531 test("cosh² (−5) − sinh² (−5)", "1", 0);
532 test("tanh 0", "0", 0);
533 test("tanh 10 − sinh 10 ÷ cosh 10", "0", 0);
535 test("atanh 0", "0", 0);
536 test("atanh (1÷10) − 0.5 ln(11÷9)", "0", 0);
538 options
.angle_units
= MP_DEGREES
;
539 test("sin 90", "1", 0);
541 options
.angle_units
= MP_RADIANS
;
542 test("sin (π÷2)", "1", 0); // FIXME: Shouldn't need brackets
544 options
.angle_units
= MP_GRADIANS
;
545 test("sin 100", "1", 0);
547 /* Complex numbers */
548 options
.angle_units
= MP_DEGREES
;
552 test("1+i", "1+i", 0);
553 test("i+1", "1+i", 0);
554 test("1−i", "1−i", 0);
555 test("i−1", "−1+i", 0);
556 test("i×i", "−1", 0);
558 test("1÷i", "−i", 0);
560 test("|3+4i|", "5", 0);
561 test("arg 0", "", PARSER_ERR_MP
);
562 test("arg 1", "0", 0);
563 test("arg (1+i)", "45", 0);
564 test("arg i", "90", 0);
565 test("arg (−1+i)", "135", 0);
566 test("arg −1", "180", 0);
567 test("arg (1+−i)", "−45", 0);
568 test("arg −i", "−90", 0);
569 test("arg (−1−i)", "−135", 0);
570 test("i⁻¹", "−i", 0);
572 test("(−1)^0.5", "i", 0);
573 test("√−4", "2i", 0);
574 test("e^iπ", "−1", 0);
575 test("log (−10) − (1 + πi÷ln(10))", "0", 0);
576 test("ln (−e) − (1 + πi)", "0", 0);
577 test("sin(iπ÷4) − i×sinh(π÷4)", "0", 0);
578 test("cos(iπ÷4) − cosh(π÷4)", "0", 0);
581 test("0 and 0", "0", 0);
582 test("1 and 0", "0", 0);
583 test("0 and 1", "0", 0);
584 test("1 and 1", "1", 0);
585 test("3 and 5", "1", 0);
587 test("0 or 0", "0", 0);
588 test("1 or 0", "1", 0);
589 test("0 or 1", "1", 0);
590 test("1 or 1", "1", 0);
591 test("3 or 5", "7", 0);
593 test("0 xor 0", "0", 0);
594 test("1 xor 0", "1", 0);
595 test("0 xor 1", "1", 0);
596 test("1 xor 1", "0", 0);
597 test("3 xor 5", "6", 0);
600 test("ones 1", "FFFFFFFE", 0);
601 test("ones 7FFFFFFF", "80000000", 0);
602 test("twos 1", "FFFFFFFF", 0);
603 test("twos 7FFFFFFF", "80000001", 0);
604 test("~7A₁₆", "FFFFFF85", 0);
608 test("1100∧1010", "1000", 0);
609 test("1100∨1010", "1110", 0);
610 test("1100⊻1010", "110", 0);
611 test("1100⊕1010", "110", 0);
612 //test("1100⊼1010", "0111", 0);
613 //test("1100⊽1010", "0001", 0);
614 //options.wordlen = 2;
615 //test("¬01₂", "10₂", 0);
616 //test("¬¬10₂", "10₂", 0);
621 print_number(MPNumber
*x
)
625 printf("sign=%d exponent=%d fraction=%d", x
->sign
, x
->exponent
, x
->fraction
[0]);
626 for (i
= 1; i
< MP_SIZE
; i
++) {
627 for (j
= i
; j
< MP_SIZE
&& x
->fraction
[j
] == 0; j
++);
632 printf(",%d", x
->fraction
[i
]);
637 test_string(const char *number
)
641 mp_set_from_string(number
, 10, &t
);
643 printf("MPNumber(%s) -> {", number
);
649 test_integer(int number
)
653 mp_set_from_integer(number
, &t
);
655 printf("MPNumber(%d) -> {", number
);
660 #include "mp-private.h"
664 printf("base=%d\n", MP_BASE
);
672 test_integer(2147483647);
677 test_string("16383");
678 test_string("16384");
679 test_string("16385");
680 test_string("268435456");
685 test_string("0.125");
686 test_string("0.0625");
687 test_string("0.00006103515625");
688 test_string("0.000030517578125");
690 test_string("1.00006103515625");
691 test_string("16384.00006103515625");
696 try(const char *string
, bool result
, bool expected
)
698 if ((result
&& !expected
) || (!result
&& expected
))
699 fail("%s -> %s, expected %s", string
, expected
? "true" : "false", result
? "true" : "false");
701 pass("%s -> %s", string
, result
? "true" : "false");
708 MPNumber zero
, one
, minus_one
;
710 mp_set_from_integer(0, &zero
);
711 mp_set_from_integer(1, &one
);
712 mp_set_from_integer(-1, &minus_one
);
714 try("mp_is_zero(-1)", mp_is_zero(&minus_one
), false);
715 try("mp_is_zero(0)", mp_is_zero(&zero
), true);
716 try("mp_is_zero(1)", mp_is_zero(&one
), false);
718 try("mp_is_negative(-1)", mp_is_negative(&minus_one
), true);
719 try("mp_is_negative(0)", mp_is_negative(&zero
), false);
720 try("mp_is_negative(1)", mp_is_negative(&one
), false);
722 try("mp_is_integer(-1)", mp_is_integer(&minus_one
), true);
723 try("mp_is_integer(0)", mp_is_integer(&zero
), true);
724 try("mp_is_integer(1)", mp_is_integer(&one
), true);
726 try("mp_is_positive_integer(-1)", mp_is_positive_integer(&minus_one
), false);
727 try("mp_is_positive_integer(0)", mp_is_positive_integer(&zero
), true);
728 try("mp_is_positive_integer(1)", mp_is_positive_integer(&one
), true);
730 try("mp_is_natural(-1)", mp_is_natural(&minus_one
), false);
731 try("mp_is_natural(0)", mp_is_natural(&zero
), false);
732 try("mp_is_natural(1)", mp_is_natural(&one
), true);
734 try("mp_is_complex(-1)", mp_is_complex(&minus_one
), false);
735 try("mp_is_complex(0)", mp_is_complex(&zero
), false);
736 try("mp_is_complex(1)", mp_is_complex(&one
), false);
738 try("mp_is_equal(-1, -1)", mp_is_equal(&minus_one
, &minus_one
), true);
739 try("mp_is_equal(-1, 0)", mp_is_equal(&minus_one
, &zero
), false);
740 try("mp_is_equal(-1, 1)", mp_is_equal(&minus_one
, &one
), false);
741 try("mp_is_equal(0, -1)", mp_is_equal(&zero
, &minus_one
), false);
742 try("mp_is_equal(0, 0)", mp_is_equal(&zero
, &zero
), true);
743 try("mp_is_equal(0, 1)", mp_is_equal(&zero
, &one
), false);
744 try("mp_is_equal(1, -1)", mp_is_equal(&one
, &minus_one
), false);
745 try("mp_is_equal(1, 0)", mp_is_equal(&one
, &zero
), false);
746 try("mp_is_equal(1, 1)", mp_is_equal(&one
, &one
), true);
748 try("mp_is_greater_than(0, -1)", mp_is_greater_than (&zero
, &minus_one
), true);
749 try("mp_is_greater_than(0, 0)", mp_is_greater_than (&zero
, &zero
), false);
750 try("mp_is_greater_than(0, 1)", mp_is_greater_than (&zero
, &one
), false);
751 try("mp_is_greater_than(1, -1)", mp_is_greater_than (&one
, &minus_one
), true);
752 try("mp_is_greater_than(1, 0)", mp_is_greater_than (&one
, &zero
), true);
753 try("mp_is_greater_than(1, 1)", mp_is_greater_than (&one
, &one
), false);
754 try("mp_is_greater_than(-1, -1)", mp_is_greater_than (&minus_one
, &minus_one
), false);
755 try("mp_is_greater_than(-1, 0)", mp_is_greater_than (&minus_one
, &zero
), false);
756 try("mp_is_greater_than(-1, 1)", mp_is_greater_than (&minus_one
, &one
), false);
758 try("mp_is_greater_equal(0, -1)", mp_is_greater_equal (&zero
, &minus_one
), true);
759 try("mp_is_greater_equal(0, 0)", mp_is_greater_equal (&zero
, &zero
), true);
760 try("mp_is_greater_equal(0, 1)", mp_is_greater_equal (&zero
, &one
), false);
761 try("mp_is_greater_equal(1, -1)", mp_is_greater_equal (&one
, &minus_one
), true);
762 try("mp_is_greater_equal(1, 0)", mp_is_greater_equal (&one
, &zero
), true);
763 try("mp_is_greater_equal(1, 1)", mp_is_greater_equal (&one
, &one
), true);
764 try("mp_is_greater_equal(-1, -1)", mp_is_greater_equal (&minus_one
, &minus_one
), true);
765 try("mp_is_greater_equal(-1, 0)", mp_is_greater_equal (&minus_one
, &zero
), false);
766 try("mp_is_greater_equal(-1, 1)", mp_is_greater_equal (&minus_one
, &one
), false);
768 try("mp_is_less_than(0, -1)", mp_is_less_than (&zero
, &minus_one
), false);
769 try("mp_is_less_than(0, 0)", mp_is_less_than (&zero
, &zero
), false);
770 try("mp_is_less_than(0, 1)", mp_is_less_than (&zero
, &one
), true);
771 try("mp_is_less_than(1, -1)", mp_is_less_than (&one
, &minus_one
), false);
772 try("mp_is_less_than(1, 0)", mp_is_less_than (&one
, &zero
), false);
773 try("mp_is_less_than(1, 1)", mp_is_less_than (&one
, &one
), false);
774 try("mp_is_less_than(-1, -1)", mp_is_less_than (&minus_one
, &minus_one
), false);
775 try("mp_is_less_than(-1, 0)", mp_is_less_than (&minus_one
, &zero
), true);
776 try("mp_is_less_than(-1, 1)", mp_is_less_than (&minus_one
, &one
), true);
778 try("mp_is_less_equal(0, -1)", mp_is_less_equal (&zero
, &minus_one
), false);
779 try("mp_is_less_equal(0, 0)", mp_is_less_equal (&zero
, &zero
), true);
780 try("mp_is_less_equal(0, 1)", mp_is_less_equal (&zero
, &one
), true);
781 try("mp_is_less_equal(1, -1)", mp_is_less_equal (&one
, &minus_one
), false);
782 try("mp_is_less_equal(1, 0)", mp_is_less_equal (&one
, &zero
), false);
783 try("mp_is_less_equal(1, 1)", mp_is_less_equal (&one
, &one
), true);
784 try("mp_is_less_equal(-1, -1)", mp_is_less_equal (&minus_one
, &minus_one
), true);
785 try("mp_is_less_equal(-1, 0)", mp_is_less_equal (&minus_one
, &zero
), true);
786 try("mp_is_less_equal(-1, 1)", mp_is_less_equal (&minus_one
, &one
), true);
793 setlocale(LC_ALL
, "C");
799 printf("Passed all %i tests\n", passes
);
800 exit(fails
> 0 ? 1 : 0);