/* ************************************************************** * C++ Mathematical Expression Toolkit Library * * * * Examples and Unit-Tests * * Author: Arash Partow (1999-2012) * * URL: http://www.partow.net/programming/exprtk/index.html * * * * Copyright notice: * * Free use of the Mathematical Expression Toolkit Library is * * permitted under the guidelines and in accordance with the * * most current version of the Common Public License. * * http://www.opensource.org/licenses/cpl1.0.php * * * ************************************************************** */ #include #include #include #include #include "exprtk.hpp" typedef std::pair test_t; static const test_t test_list[] = { // Note: The each of following tests should // all compile down to a single literal node. test_t("0",0.0), test_t("1",1.0), test_t("2",2.0), test_t("3",3.0), test_t("4",4.0), test_t("5",5.0), test_t("6",6.0), test_t("7",7.0), test_t("8",8.0), test_t("9",9.0), test_t("12.12",12.12), test_t("123.123",123.123), test_t("1234.1234",1234.1234), test_t("12345.12345",12345.12345), test_t("123456.123456",123456.123456), test_t("0.0",0.0), test_t("1.0",1.0), test_t("2.0",2.0), test_t("3.0",3.0), test_t("4.0",4.0), test_t("5.0",5.0), test_t("6.0",6.0), test_t("7.0",7.0), test_t("8.0",8.0), test_t("9.0",9.0), test_t("0.0",0.0), test_t("1.1",1.1), test_t("2.2",2.2), test_t("3.3",3.3), test_t("4.4",4.4), test_t("5.5",5.5), test_t("6.6",6.6), test_t("7.7",7.7), test_t("8.8",8.8), test_t("9.9",9.9), test_t("+0",0.0), test_t("+1",1.0), test_t("+2",2.0), test_t("+3",3.0), test_t("+4",4.0), test_t("+5",5.0), test_t("+6",6.0), test_t("+7",7.0), test_t("+8",8.0), test_t("+9",9.0), test_t("+0.0",0.0), test_t("+1.0",1.0), test_t("+2.0",2.0), test_t("+3.0",3.0), test_t("+4.0",4.0), test_t("+5.0",5.0), test_t("+6.0",6.0), test_t("+7.0",7.0), test_t("+8.0",8.0), test_t("+9.0",9.0), test_t("+0.0",0.0), test_t("+1.1",1.1), test_t("+2.2",2.2), test_t("+3.3",3.3), test_t("+4.4",4.4), test_t("+5.5",5.5), test_t("+6.6",6.6), test_t("+7.7",7.7), test_t("+8.8",8.8), test_t("+9.9",9.9), test_t("-0",-0.0), test_t("-1",-1.0), test_t("-2",-2.0), test_t("-3",-3.0), test_t("-4",-4.0), test_t("-5",-5.0), test_t("-6",-6.0), test_t("-7",-7.0), test_t("-8",-8.0), test_t("-9",-9.0), test_t("-0.0",-0.0), test_t("-1.0",-1.0), test_t("-2.0",-2.0), test_t("-3.0",-3.0), test_t("-4.0",-4.0), test_t("-5.0",-5.0), test_t("-6.0",-6.0), test_t("-7.0",-7.0), test_t("-8.0",-8.0), test_t("-9.0",-9.0), test_t("-0.0",-0.0), test_t("-1.1",-1.1), test_t("-2.2",-2.2), test_t("-3.3",-3.3), test_t("-4.4",-4.4), test_t("-5.5",-5.5), test_t("-6.6",-6.6), test_t("-7.7",-7.7), test_t("-8.8",-8.8), test_t("-9.9",-9.9), test_t("0.0e+0",+0.0e+0), test_t("1.1e+1",+1.1e+1), test_t("2.2e+2",+2.2e+2), test_t("3.3e+3",+3.3e+3), test_t("4.4e+4",+4.4e+4), test_t("5.5e+5",+5.5e+5), test_t("6.6e+6",+6.6e+6), test_t("7.7e+7",+7.7e+7), test_t("8.8e+8",+8.8e+8), test_t("9.9e+9",+9.9e+9), test_t("-0.0e+0",-0.0e+0), test_t("-1.1e+1",-1.1e+1), test_t("-2.2e+2",-2.2e+2), test_t("-3.3e+3",-3.3e+3), test_t("-4.4e+4",-4.4e+4), test_t("-5.5e+5",-5.5e+5), test_t("-6.6e+6",-6.6e+6), test_t("-7.7e+7",-7.7e+7), test_t("-8.8e+8",-8.8e+8), test_t("-9.9e+9",-9.9e+9), test_t("0.0E+0",+0.0E+0), test_t("1.1E+1",+1.1E+1), test_t("2.2E+2",+2.2E+2), test_t("3.3E+3",+3.3E+3), test_t("4.4E+4",+4.4E+4), test_t("5.5E+5",+5.5E+5), test_t("6.6E+6",+6.6E+6), test_t("7.7E+7",+7.7E+7), test_t("8.8E+8",+8.8E+8), test_t("9.9E+9",+9.9E+9), test_t("-0.0E+0",-0.0E+0), test_t("-1.1E+1",-1.1E+1), test_t("-2.2E+2",-2.2E+2), test_t("-3.3E+3",-3.3E+3), test_t("-4.4E+4",-4.4E+4), test_t("-5.5E+5",-5.5E+5), test_t("-6.6E+6",-6.6E+6), test_t("-7.7E+7",-7.7E+7), test_t("-8.8E+8",-8.8E+8), test_t("-9.9E+9",-9.9E+9), test_t("(0)",0.0), test_t("(1)",1.0), test_t("(2)",2.0), test_t("(3)",3.0), test_t("(4)",4.0), test_t("(5)",5.0), test_t("(6)",6.0), test_t("(7)",7.0), test_t("(8)",8.0), test_t("(9)",9.0), test_t("(0.0)",0.0), test_t("(1.0)",1.0), test_t("(2.0)",2.0), test_t("(3.0)",3.0), test_t("(4.0)",4.0), test_t("(5.0)",5.0), test_t("(6.0)",6.0), test_t("(7.0)",7.0), test_t("(8.0)",8.0), test_t("(9.0)",9.0), test_t("(0.0)",0.0), test_t("(1.1)",1.1), test_t("(2.2)",2.2), test_t("(3.3)",3.3), test_t("(4.4)",4.4), test_t("(5.5)",5.5), test_t("(6.6)",6.6), test_t("(7.7)",7.7), test_t("(8.8)",8.8), test_t("(9.9)",9.9), test_t("(+0)",0.0), test_t("(+1)",1.0), test_t("(+2)",2.0), test_t("(+3)",3.0), test_t("(+4)",4.0), test_t("(+5)",5.0), test_t("(+6)",6.0), test_t("(+7)",7.0), test_t("(+8)",8.0), test_t("(+9)",9.0), test_t("(+0.0)",0.0), test_t("(+1.0)",1.0), test_t("(+2.0)",2.0), test_t("(+3.0)",3.0), test_t("(+4.0)",4.0), test_t("(+5.0)",5.0), test_t("(+6.0)",6.0), test_t("(+7.0)",7.0), test_t("(+8.0)",8.0), test_t("(+9.0)",9.0), test_t("(+0.0)",0.0), test_t("(+1.1)",1.1), test_t("(+2.2)",2.2), test_t("(+3.3)",3.3), test_t("(+4.4)",4.4), test_t("(+5.5)",5.5), test_t("(+6.6)",6.6), test_t("(+7.7)",7.7), test_t("(+8.8)",8.8), test_t("(+9.9)",9.9), test_t("(-0)",-0.0), test_t("(-1)",-1.0), test_t("(-2)",-2.0), test_t("(-3)",-3.0), test_t("(-4)",-4.0), test_t("(-5)",-5.0), test_t("(-6)",-6.0), test_t("(-7)",-7.0), test_t("(-8)",-8.0), test_t("(-9)",-9.0), test_t("(-0.0)",-0.0), test_t("(-1.0)",-1.0), test_t("(-2.0)",-2.0), test_t("(-3.0)",-3.0), test_t("(-4.0)",-4.0), test_t("(-5.0)",-5.0), test_t("(-6.0)",-6.0), test_t("(-7.0)",-7.0), test_t("(-8.0)",-8.0), test_t("(-9.0)",-9.0), test_t("(-0.0)",-0.0), test_t("(-1.1)",-1.1), test_t("(-2.2)",-2.2), test_t("(-3.3)",-3.3), test_t("(-4.4)",-4.4), test_t("(-5.5)",-5.5), test_t("(-6.6)",-6.6), test_t("(-7.7)",-7.7), test_t("(-8.8)",-8.8), test_t("(-9.9)",-9.9), test_t("1234567890",1234567890), test_t("123456789.0",123456789.0), test_t("+1234567890",1234567890), test_t("+123456789.0",123456789.0), test_t("-1234567890",-1234567890), test_t("-123456789.0",-123456789.0), test_t("1234.567890",1234.567890), test_t("-1234.567890",-1234.567890), test_t("0+9",9.0), test_t("1+8",9.0), test_t("2+7",9.0), test_t("3+6",9.0), test_t("4+5",9.0), test_t("5+4",9.0), test_t("6+3",9.0), test_t("7+2",9.0), test_t("8+1",9.0), test_t("9+0",9.0), test_t(" 0 + 9 ",9.0), test_t(" 1 + 8 ",9.0), test_t(" 2 + 7 ",9.0), test_t(" 3 + 6 ",9.0), test_t(" 4 + 5 ",9.0), test_t(" 5 + 4 ",9.0), test_t(" 6 + 3 ",9.0), test_t(" 7 + 2 ",9.0), test_t(" 8 + 1 ",9.0), test_t(" 9 + 0 ",9.0), test_t("( 0 + 9 )",9.0), test_t("( 1 + 8 )",9.0), test_t("( 2 + 7 )",9.0), test_t("( 3 + 6 )",9.0), test_t("( 4 + 5 )",9.0), test_t("( 5 + 4 )",9.0), test_t("( 6 + 3 )",9.0), test_t("( 7 + 2 )",9.0), test_t("( 8 + 1 )",9.0), test_t("( 9 + 0 )",9.0), test_t("1+2",+3.0), test_t("1-2",-1.0), test_t("1*2",+2.0), test_t("1/2",+0.5), test_t("1.1+2.2", +3.3), test_t("1.1-2.2", -1.1), test_t("1.1*2.2",+2.42), test_t("1.1/2.2", +0.5), test_t("0-9",-9.0), test_t("1-8",-7.0), test_t("2-7",-5.0), test_t("3-6",-3.0), test_t("4-5",-1.0), test_t("5-4",+1.0), test_t("6-3",+3.0), test_t("7-2",+5.0), test_t("8-1",+7.0), test_t("9-0",+9.0), test_t(" 0 - 9 ",-9.0), test_t(" 1 - 8 ",-7.0), test_t(" 2 - 7 ",-5.0), test_t(" 3 - 6 ",-3.0), test_t(" 4 - 5 ",-1.0), test_t(" 5 - 4 ",+1.0), test_t(" 6 - 3 ",+3.0), test_t(" 7 - 2 ",+5.0), test_t(" 8 - 1 ",+7.0), test_t(" 9 - 0 ",+9.0), test_t("( 0 - 9 )",-9.0), test_t("( 1 - 8 )",-7.0), test_t("( 2 - 7 )",-5.0), test_t("( 3 - 6 )",-3.0), test_t("( 4 - 5 )",-1.0), test_t("( 5 - 4 )",+1.0), test_t("( 6 - 3 )",+3.0), test_t("( 7 - 2 )",+5.0), test_t("( 8 - 1 )",+7.0), test_t("( 9 - 0 )",+9.0), test_t("1.1+2.2+3.3",+6.6), test_t("+1.1+2.2+3.3",+6.6), test_t("-1.1-2.2-3.3",-6.6), test_t("1.1*2.2*3.3",+7.986), test_t("+1.1*2.2*3.3",+7.986), test_t("-1.1*-2.2*-3.3",-7.986), test_t("1 + 1/2",+1.5), test_t("1 + (1/2)",+1.5), test_t("1.1 + 1.1/2.2",+1.6), test_t("1.1 + (1.1/2.2)",+1.6), test_t("2 * 1/2",+1.0), test_t("2 * (1/2)",+1.0), test_t("2.2 * 1.1/2.2",+1.1), test_t("2.2 * (1.1/2.2)",+1.1), test_t("1^2",1.0), test_t("2^1",2.0), test_t("2^3",8.0), test_t("-2^3",-8.0), test_t("-2^4",-16.0), test_t("(-2)^3",-8.0), test_t("(-2)^4",+16.0), test_t("3^2^1",9.0), test_t("1.1^2.2",1.23328630055466251099), test_t("2.2^1.1",2.3804822576003541627), test_t("2.2^3.3",13.48946876053338489127), test_t("3.3^2.2^1.1",17.15193942371376191362), test_t("1.1^(1.1 * 2.2)", 1.25941916576299080582), test_t("2.2^(1.1 * 3.3)",17.49823848953534759743), test_t("3.3^(1.1 * 2.2)",17.98058156638874965269), test_t("1.23^3 == (1.23 * 1.23 * 1.23)",1.0), test_t("equal(1.23^-3,1/(1.23 * 1.23 * 1.23))",1.0), test_t("(2 + 1.23^3) == (2 + (1.23 * 1.23 * 1.23))",1.0), test_t("(2 - 1.23^3) == (2 - (1.23 * 1.23 * 1.23))",1.0), test_t("(2 * 1.23^3) == (2 * (1.23 * 1.23 * 1.23))",1.0), test_t("(2 / 1.23^3) == (2 / (1.23 * 1.23 * 1.23))",1.0), test_t("(1.23^3 + 2) == ((1.23 * 1.23 * 1.23) + 2)",1.0), test_t("(1.23^3 - 2) == ((1.23 * 1.23 * 1.23) - 2)",1.0), test_t("(1.23^3 * 2) == ((1.23 * 1.23 * 1.23) * 2)",1.0), test_t("(1.23^3 / 2) == ((1.23 * 1.23 * 1.23) / 2)",1.0), test_t("equal(1.0^(1.0/2.0),sqrt(1.0))",1.0), test_t("equal(1.0^(1.0/2.0),root(1.0,2.0))",1.0), test_t("equal(1.0^(1.0/3.0),root(1.0,3.0))",1.0), test_t("equal(1.0^(1.0/4.0),root(1.0,4.0))",1.0), test_t("equal(1.0^(1.0/5.0),root(1.0,5.0))",1.0), test_t("equal(1.0^(1.0/6.0),root(1.0,6.0))",1.0), test_t("equal(1.0^(1.0/7.0),root(1.0,7.0))",1.0), test_t("equal(1.0^(1.0/8.0),root(1.0,8.0))",1.0), test_t("equal(1.0^(1.0/9.0),root(1.0,9.0))",1.0), test_t("equal(2.0^(1.0/2.0),sqrt(2.0))",1.0), test_t("equal(2.0^(1.0/2.0),root(2.0,2.0))",1.0), test_t("equal(3.0^(1.0/3.0),root(3.0,3.0))",1.0), test_t("equal(4.0^(1.0/4.0),root(4.0,4.0))",1.0), test_t("equal(5.0^(1.0/5.0),root(5.0,5.0))",1.0), test_t("equal(6.0^(1.0/6.0),root(6.0,6.0))",1.0), test_t("equal(7.0^(1.0/7.0),root(7.0,7.0))",1.0), test_t("equal(8.0^(1.0/8.0),root(8.0,8.0))",1.0), test_t("equal(9.0^(1.0/9.0),root(9.0,9.0))",1.0), test_t("1 < 2", 1.0), test_t("1 <= 2", 1.0), test_t("1.1 <= 2.2", 1.0), test_t("(1.0 + 0.1) <= (2.0 + 0.2)", 1.0), test_t("1 > 2", 0.0), test_t("1 >= 2", 0.0), test_t("1.1 >= 2.2", 0.0), test_t("(1.0 + 0.1) >= (2.0 + 0.2)", 0.0), test_t("1 <> 2", 1.0), test_t("1 != 2", 1.0), test_t("1.1 <> 2.2", 1.0), test_t("1.1 != 2.2", 1.0), test_t("(1.0 + 0.1) <> (2.0 + 0.2)", 1.0), test_t("(1.0 + 0.1) != (2.0 + 0.2)", 1.0), test_t("1 == 1", 1.0), test_t("1.1 == 1.1", 1.0), test_t("1 = 1", 1.0), test_t("1.1 = 1.1", 1.0), test_t("1 <> 1", 0.0), test_t("1 != 1", 0.0), test_t("1.1 <> 1.1", 0.0), test_t("1.1 != 1.1", 0.0), test_t("(1.0 + 0.1) <> (1.0 + 0.1)", 0.0), test_t("(1.0 + 0.1) != (1.0 + 0.1)", 0.0), test_t("equal(1.1,1.1)",1.0), test_t("equal(1.1,2.2)",0.0), test_t("not_equal(1.1,1.1)",0.0), test_t("not_equal(1.1,2.2)",1.0), test_t("1 and 1",1.0), test_t("1 and 0",0.0), test_t("0 and 1",0.0), test_t("0 and 0",0.0), test_t("1 nand 1",0.0), test_t("1 nand 0",1.0), test_t("0 nand 1",1.0), test_t("0 nand 0",1.0), test_t("1 or 1",1.0), test_t("1 or 0",1.0), test_t("0 or 1",1.0), test_t("0 or 0",0.0), test_t("1 nor 1",0.0), test_t("1 nor 0",0.0), test_t("0 nor 1",0.0), test_t("0 nor 0",1.0), test_t("0 xor 0",0.0), test_t("0 xor 1",1.0), test_t("1 xor 0",1.0), test_t("1 xor 1",0.0), test_t("1.0 and 1.0",1.0), test_t("1.0 and 0.0",0.0), test_t("0.0 and 1.0",0.0), test_t("0.0 and 0.0",0.0), test_t("1.0 nand 1.0",0.0), test_t("1.0 nand 0.0",1.0), test_t("0.0 nand 1.0",1.0), test_t("0.0 nand 0.0",1.0), test_t("1.0 or 1.0",1.0), test_t("1.0 or 0.0",1.0), test_t("0.0 or 1.0",1.0), test_t("0.0 or 0.0",0.0), test_t("1.0 nor 1.0",0.0), test_t("1.0 nor 0.0",0.0), test_t("0.0 nor 1.0",0.0), test_t("0.0 nor 0.0",1.0), test_t("0.0 xor 0.0",0.0), test_t("0.0 xor 1.0",1.0), test_t("1.0 xor 0.0",1.0), test_t("1.0 xor 1.0",0.0), test_t("(1 and 1)",1.0), test_t("(1 and 0)",0.0), test_t("(0 and 1)",0.0), test_t("(0 and 0)",0.0), test_t("(1 nand 1)",0.0), test_t("(1 nand 0)",1.0), test_t("(0 nand 1)",1.0), test_t("(0 nand 0)",1.0), test_t("(1 or 1)",1.0), test_t("(1 or 0)",1.0), test_t("(0 or 1)",1.0), test_t("(0 or 0)",0.0), test_t("(1 nor 1)",0.0), test_t("(1 nor 0)",0.0), test_t("(0 nor 1)",0.0), test_t("(0 nor 0)",1.0), test_t("(0 xor 0)",0.0), test_t("(0 xor 1)",1.0), test_t("(1 xor 0)",1.0), test_t("(1 xor 1)",0.0), test_t("(1.0 and 1.0)",1.0), test_t("(1.0 and 0.0)",0.0), test_t("(0.0 and 1.0)",0.0), test_t("(0.0 and 0.0)",0.0), test_t("(1.0 nand 1.0)",0.0), test_t("(1.0 nand 0.0)",1.0), test_t("(0.0 nand 1.0)",1.0), test_t("(0.0 nand 0.0)",1.0), test_t("(1.0 or 1.0)",1.0), test_t("(1.0 or 0.0)",1.0), test_t("(0.0 or 1.0)",1.0), test_t("(0.0 or 0.0)",0.0), test_t("(1.0 nor 1.0)",0.0), test_t("(1.0 nor 0.0)",0.0), test_t("(0.0 nor 1.0)",0.0), test_t("(0.0 nor 0.0)",1.0), test_t("(0.0 xor 0.0)",0.0), test_t("(0.0 xor 1.0)",1.0), test_t("(1.0 xor 0.0)",1.0), test_t("(1.0 xor 1.0)",0.0), test_t("(1 nand 1) == not(1 and 1)",1.0), test_t("(1 nand 0) == not(1 and 0)",1.0), test_t("(0 nand 1) == not(0 and 1)",1.0), test_t("(0 nand 0) == not(0 and 0)",1.0), test_t("(1 nor 1) == not(1 or 1)",1.0), test_t("(1 nor 0) == not(1 or 0)",1.0), test_t("(0 nor 1) == not(0 or 1)",1.0), test_t("(0 nor 0) == not(0 or 0)",1.0), test_t("abs(1)",1.0), test_t("abs(-1)",1.0), test_t("abs(1.0)",1.0), test_t("abs(-1.0)",1.0), test_t("min(1,2)",1.0), test_t("min(1,2,3)",1.0), test_t("min(1,2,3,4)",1.0), test_t("min(1,2,3,4,5)",1.0), test_t("min(1,2,3,4,5,6)",1.0), test_t("min(1.1,2.2)",1.1), test_t("min(1.1,2.2,3.3)",1.1), test_t("min(1.1,2.2,3.3,4.4)",1.1), test_t("min(1.1,2.2,3.3,4.4,5.5)",1.1), test_t("min(1.1,2.2,3.3,4.4,5.5,6.6)",1.1), test_t("min(min(1,2),min(3,4))",1.0), test_t("max(1,2)",2.0), test_t("max(1,2,3)",3.0), test_t("max(1,2,3,4)",4.0), test_t("max(1,2,3,4,5)",5.0), test_t("max(1,2,3,4,5,6)",6.0), test_t("max(1.1,2.2)",2.2), test_t("max(1.1,2.2,3.3)",3.3), test_t("max(1.1,2.2,3.3,4.4)",4.4), test_t("max(1.1,2.2,3.3,4.4,5.5)",5.5), test_t("max(1.1,2.2,3.3,4.4,5.5,6.6)",6.6), test_t("max(max(1,2),max(3,4))",4.0), test_t("avg(1,2)",1.5), test_t("avg(1,2,3)",2.0), test_t("avg(1,2,3,4)",2.5), test_t("avg(1,2,3,4,5)",3.0), test_t("avg(1.1,2.2)",1.65), test_t("avg(1.1,2.2,3.3)",2.2), test_t("avg(1.1,2.2,3.3,4.4)",2.75), test_t("avg(1.1,2.2,3.3,4.4,5.5)",3.3), test_t("avg(1.1,2.2,3.3,4.4,5.5,6.6)",3.85), test_t("sum(1,2)",3.0), test_t("sum(1,2,3)",6.0), test_t("sum(1,2,3,4)",10), test_t("sum(1,2,3,4,5)",15.0), test_t("sum(1,2,3,4,5,6)",21), test_t("sum(1.1,2.2)",3.3), test_t("sum(1.1,2.2,3.3)",6.6), test_t("sum(1.1,2.2,3.3,4.4)",11.0), test_t("sum(1.1,2.2,3.3,4.4,5.5)",16.5), test_t("sum(1.1,2.2,3.3,4.4,5.5,6.6)",23.1), test_t("mul(1,2)",2.0), test_t("mul(1,2,3)",6.0), test_t("mul(1,2,3,4)",24.0), test_t("mul(1,2,3,4,5)",120.0), test_t("mul(1,2,3,4,5,6)",720.0), test_t("mul(1.1,2.2)",2.42), test_t("mul(1.1,2.2,3.3)",7.986), test_t("mul(1.1,2.2,3.3,4.4)",35.1384), test_t("mul(1.1,2.2,3.3,4.4,5.5)",193.2612), test_t("mul(1.1,2.2,3.3,4.4,5.5,6.6)",1275.52392), test_t("floor(1.0)",1.0), test_t("floor(1.1)",1.0), test_t("floor(-1.0)",-1.0), test_t("floor(-1.1)",-2.0), test_t("ceil(1.0)",1.0), test_t("ceil(1.1)",2.0), test_t("ceil(-1.0)",-1.0), test_t("ceil(-1.1)",-1.0), test_t("round(1.1)",1.0), test_t("round(1.49)",1.0), test_t("round(1.5)",2.0), test_t("round(1.9)",2.0), test_t("roundn(1/3,2)",0.33), test_t("roundn(1/3,5)",0.33333), test_t("roundn(2/3,2)",0.67), test_t("roundn(2/3,5)",0.66667), test_t("roundn(1.0/3.0,2.0)",0.33), test_t("roundn(1.0/3.0,5.0)",0.33333), test_t("roundn(2.0/3.0,2.0)",0.67), test_t("roundn(2.0/3.0,5.0)",0.66667), test_t("cos(0.0)",1.0), test_t("sin(0.0)",0.0), test_t("equal(sin(pi/4.0),cos(pi/4.0))",1.0), test_t("equal(sin(pi/6.0),cos(pi/3.0))",1.0), test_t("(sin(pi/4.0) - cos(pi/4.0)) <= epsilon",1.0), test_t("(cos(pi/3.0) - sin(pi/6.0)) <= epsilon",1.0), test_t("sin(deg2rad(30))",0.5), test_t("cos(deg2rad(60))",0.5), test_t("sin(deg2rad(30)) + cos(deg2rad(60))",1.0), test_t("equal(sin(deg2rad(30))/cos(deg2rad(30)),tan(deg2rad(30)))",1.0), test_t("exp(1.0)",2.71828182845904523536028747135266249775724), test_t("exp(0.0)",1.0), test_t("log(2.7182818284590451)",1.0), test_t("log10(10.0)",1.0), test_t("hyp(3.0,4.0)",5.0), test_t("hyp(1.0,sqrt(3.0))",2.0), test_t("if(1 < 2, 3, 4)",3.0), test_t("if(1.1 < 2.2, 3.3, 4.4)",3.3), test_t("if((1.0+1.1) < (2.0+1.2), 3.3, 4.4)",3.3), test_t("if(1 = 2, 3, 4)",4.0), test_t("if(1.1 = 2.2, 3.3, 4.4)",4.4), test_t("if((1.0+1.1) = (2.0+1.2), 3.3, 4.4)",4.4), test_t("if(1 == 2, 3, 4)",4.0), test_t("if(1.1 == 2.2, 3.3, 4.4)",4.4), test_t("if((1.0+1.1) == (2.0+1.2), 3.3, 4.4)",4.4), test_t("if(1 >= 2, 3, 4)",4.0), test_t("if(1.1 >= 2.2, 3.3, 4.4)",4.4), test_t("if((1.0+1.1) >= (2.0+1.2), 3.3, 4.4)",4.4), test_t("if(((1.0 + 2.0) == 3.0) and ((4.0 + 5.0) < 9.0),1,2)",2.0), test_t("(3.0 - 1.0 - 2.0) == ((3.0 - 1.0) - 2.0)",1.0), test_t("clamp(-1,1,+1)",1.0), test_t("clamp(-1,-1.5,+1.0)",-1.0), test_t("clamp(-1,+1.5,+1.0)",+1.0), test_t("clamp(-1,-1.5,+1.0) + clamp(-1,+1.5,+1.0)",0.0), test_t("inrange(-2,1,+2) == ((-2 <= 1) and (1 <= +2))",1.0), test_t("inrange(-2,1,+2) == if(({-2 <= 1} and [1 <= +2]),1.0,0.0)",1.0), test_t("sgn( 0)", 0.0), test_t("sgn(+3)",+1.0), test_t("sgn(-3)",-1.0), test_t("equal($f00(1.1,2.2,3.3),((1.1+2.2)/3.3))",1.0), test_t("equal($f01(1.1,2.2,3.3),((1.1+2.2)*3.3))",1.0), test_t("equal($f02(1.1,2.2,3.3),((1.1-2.2)/3.3))",1.0), test_t("equal($f03(1.1,2.2,3.3),((1.1-2.2)*3.3))",1.0), test_t("equal($f04(1.1,2.2,3.3),((1.1*2.2)+3.3))",1.0), test_t("equal($f05(1.1,2.2,3.3),((1.1*2.2)-3.3))",1.0), test_t("equal($f06(1.1,2.2,3.3),((1.1*2.2)/3.3))",1.0), test_t("equal($f07(1.1,2.2,3.3),((1.1*2.2)*3.3))",1.0), test_t("equal($f08(1.1,2.2,3.3),((1.1/2.2)+3.3))",1.0), test_t("equal($f09(1.1,2.2,3.3),((1.1/2.2)-3.3))",1.0), test_t("equal($f10(1.1,2.2,3.3),((1.1/2.2)/3.3))",1.0), test_t("equal($f11(1.1,2.2,3.3),((1.1/2.2)*3.3))",1.0), test_t("equal($f12(1.1,2.2,3.3),(3.3/(1.1+2.2)))",1.0), test_t("equal($f13(1.1,2.2,3.3),(3.3/(1.1-2.2)))",1.0), test_t("equal($f14(1.1,2.2,3.3),(3.3/(1.1*2.2)))",1.0), test_t("equal($f15(1.1,2.2,3.3),(3.3/(1.1/2.2)))",1.0), test_t("equal($f16(1.1,2.2,3.3),(3.3-(1.1/2.2)))",1.0), test_t("equal($f17(1.1,2.2,3.3),(3.3-(1.1/2.2)))",1.0), test_t("equal($f18(1.1,2.2,3.3,4.4),(4.4+((1.1+2.2)/3.3)))",1.0), test_t("equal($f19(1.1,2.2,3.3,4.4),(4.4+((1.1+2.2)*3.3)))",1.0), test_t("equal($f20(1.1,2.2,3.3,4.4),(4.4+((1.1-2.2)/3.3)))",1.0), test_t("equal($f21(1.1,2.2,3.3,4.4),(4.4+((1.1-2.2)*3.3)))",1.0), test_t("equal($f22(1.1,2.2,3.3,4.4),(4.4+((1.1*2.2)/3.3)))",1.0), test_t("equal($f23(1.1,2.2,3.3,4.4),(4.4+((1.1*2.2)*3.3)))",1.0), test_t("equal($f24(1.1,2.2,3.3,4.4),(4.4+((1.1/2.2)+3.3)))",1.0), test_t("equal($f25(1.1,2.2,3.3,4.4),(4.4+((1.1/2.2)/3.3)))",1.0), test_t("equal($f26(1.1,2.2,3.3,4.4),(4.4+((1.1/2.2)*3.3)))",1.0), test_t("equal($f27(1.1,2.2,3.3,4.4),(4.4-((1.1+2.2)/3.3)))",1.0), test_t("equal($f28(1.1,2.2,3.3,4.4),(4.4-((1.1+2.2)*3.3)))",1.0), test_t("equal($f29(1.1,2.2,3.3,4.4),(4.4-((1.1-2.2)/3.3)))",1.0), test_t("equal($f30(1.1,2.2,3.3,4.4),(4.4-((1.1-2.2)*3.3)))",1.0), test_t("equal($f31(1.1,2.2,3.3,4.4),(4.4-((1.1*2.2)/3.3)))",1.0), test_t("equal($f32(1.1,2.2,3.3,4.4),(4.4-((1.1*2.2)*3.3)))",1.0), test_t("equal($f33(1.1,2.2,3.3,4.4),(4.4-((1.1/2.2)/3.3)))",1.0), test_t("equal($f34(1.1,2.2,3.3,4.4),(4.4-((1.1/2.2)*3.3)))",1.0), test_t("equal($f35(1.1,2.2,3.3,4.4),(((1.1+2.2)*3.3)-4.4))",1.0), test_t("equal($f36(1.1,2.2,3.3,4.4),(((1.1-2.2)*3.3)-4.4))",1.0), test_t("equal($f37(1.1,2.2,3.3,4.4),(((1.1*2.2)*3.3)-4.4))",1.0), test_t("equal($f38(1.1,2.2,3.3,4.4),(((1.1/2.2)*3.3)-4.4))",1.0), test_t("equal($f39(1.1,2.2,3.3,4.4),(((1.1+2.2)/3.3)-4.4))",1.0), test_t("equal($f40(1.1,2.2,3.3,4.4),(((1.1-2.2)/3.3)-4.4))",1.0), test_t("equal($f41(1.1,2.2,3.3,4.4),(((1.1*2.2)/3.3)-4.4))",1.0), test_t("equal($f42(1.1,2.2,3.3,4.4),(((1.1/2.2)/3.3)-4.4))",1.0), test_t("1+2+3+4+5+6+7+8+9+0",45.0), test_t("1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0",45.0), test_t("1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0 + 8.0 + 9.0 + 0.0",45.0), test_t("(1+2)+(3+4)+(5+6)+(7+8)+(9+0)",45.0), test_t("(1-2)+(3-4)+(5-6)+(7-8)+(9-0)",+5.0), test_t("(1+2)-(3+4)-(5+6)-(7+8)-(9+0)",-39.0), test_t("(1.0+2.0)+(3.0+4.0)+(5.0+6.0)+(7.0+8.0)+(9.0+0.0)",45.0), test_t("(1.0-2.0)+(3.0-4.0)+(5.0-6.0)+(7.0-8.0)+(9.0-0.0)",+5.0), test_t("(1.0+2.0)-(3.0+4.0)-(5.0+6.0)-(7.0+8.0)-(9.0+0.0)",-39.0), test_t("[(1.0+2.0)+[3.0+4.0]+(5.0+6.0)]+([7.0+8.0]+(9.0+0.0))",45.0), test_t("([1.0-2.0]+(3.0-4.0)+[5.0-6.0])+[(7.0-8.0)+[9.0-0.0]]",+5.0), test_t("((1.0+2.0))-[(3.0+4.0)]-((5.0+6.0))-[(7.0+8.0)]-((9.0+0.0))",-39.0), test_t("{[(1.0+2.0)+[3.0+4.0]+({5.0+6.0})]}+({[7.0+8.0]+(9.0+0.0)})",45.0), test_t("{([1.0-2.0]+(3.0-4.0)+[5.0-6.0])}+[({+7.0}-{+8.0})+[{+9.0-0.0}]]",+5.0), test_t("((+1.0+2.0))-[({+3.0+4.0})]-(({+5.0+6.0}))-[({+7.0}+8.0)]-(({+9.0}+{0.0}))",-39.0), test_t("1+2-3*4/5+6-7*8/9+0",0.37777777777777777778), test_t("1.1+2.2-3.3*4.4/5.5+6.6-7.7*8.8/9.9+0.0",0.41555555555555555556), test_t("(1+2)-(3*4)/(5+6)-(7*8)/(9+0)",-4.31313131313131313131), test_t("1/1+1/2+1/3+1/4+1/5+1/6+1/7+1/8+1/9",2.82896825396825396825), test_t("(1/1)+(1/2)+(1/3)+(1/4)+(1/5)+(1/6)+(1/7)+(1/8)+(1/9)",2.82896825396825396825), test_t("1.0/1.0+1.0/2.0+1.0/3.0+1.0/4.0+1.0/5.0+1.0/6.0+1.0/7.0+1.0/8.0+1.0/9",2.82896825396825396825), test_t("(1.0/1.0)+(1.0/2.0)+(1.0/3.0)+(1.0/4.0)+(1.0/5.0)+(1.0/6.0)+(1.0/7.0)+(1.0/8.0)+(1.0/9)",2.82896825396825396825), test_t("1/1*1/2*1/3*1/4*1/5*1/6*1/7*1/8*1/9",0.00000275573192239859), test_t("(1/1)*(1/2)*(1/3)*(1/4)*(1/5)*(1/6)*(1/7)*(1/8)*(1/9)",0.00000275573192239859), test_t("1.0/1.0*1.0/2.0*1.0/3.0*1.0/4.0*1.0/5.0*1.0/6.0*1.0/7.0*1.0/8.0*1.0/9",0.00000275573192239859), test_t("(1.0/1.0)*(1.0/2.0)*(1.0/3.0)*(1.0/4.0)*(1.0/5.0)*(1.0/6.0)*(1.0/7.0)*(1.0/8.0)*(1.0/9)",0.00000275573192239859) }; static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_t); template inline bool not_equal(const T& t1, const T& t2, const T& epsilon = 0.0000000001/*std::numeric_limits::epsilon()*/) { if (t1 != t1) return true; if (t2 != t2) return true; return std::abs(t1 - t2) > (std::max(T(1.0),std::max(std::abs(t1),std::abs(t2))) * epsilon); } template inline bool test_expression(const std::string& expression_string, const T& expected_result) { exprtk::symbol_table symbol_table; symbol_table.add_constants(); exprtk::expression expression; expression.register_symbol_table(symbol_table); { exprtk::parser parser; if (!parser.compile(expression_string,expression)) { std::cout << "test_expression() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } } T result = expression.value(); if (not_equal(result,expected_result)) { printf("Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n", expression_string.c_str(), expected_result, result); return false; } return true; } template inline bool run_test00() { const std::size_t rounds = 100; for (std::size_t r = 0; r < rounds; ++r) { for (std::size_t i = 0; i < test_list_size; ++i) { if (!test_expression(test_list[i].first,T(test_list[i].second))) return false; } } return true; } template struct test_xy { test_xy(std::string e, const T& v0, const T& v1, const T& r) : expr(e), x(v0), y(v1), result(r) {} std::string expr; T x; T y; T result; }; template inline bool run_test01() { static const test_xy test_list[] = { test_xy("x + y" ,T(2.2),T(3.3),T(5.5 )), test_xy("x - y" ,T(3.3),T(2.2),T(1.1 )), test_xy("x * y" ,T(3.3),T(2.2),T(7.26 )), test_xy("x / y" ,T(3.3),T(2.2),T(1.5 )), test_xy("(x + y) * (x + y)" ,T(2.2),T(3.3),T(30.25)), test_xy("(x + y) / (x + y)" ,T(2.2),T(3.3),T(1.0 )), test_xy("x + y > x and x + y > y" ,T(2.2),T(3.3),T(1.0)), test_xy("1 + (x + y)" ,T(2.2),T(3.3),T(6.5 )), test_xy("(x + y) - 1" ,T(2.2),T(3.3),T(4.5 )), test_xy("1 + (x + y) * 2" ,T(2.2),T(3.3),T(12.0 )), test_xy("2 * (x + y) - 1" ,T(2.2),T(3.3),T(10.0 )), test_xy("y + (x + 1)" ,T(2.2),T(3.3),T(6.5 )), test_xy("(x + 1) + y" ,T(2.2),T(3.3),T(6.5 )), test_xy("2 * x" ,T(2.2),T(0.0),T(4.4)), test_xy("x * 2" ,T(2.2),T(0.0),T(4.4)), test_xy("1.1 + x",T(2.2),T(0.0),T(3.3)), test_xy("x + 1.1",T(2.2),T(0.0),T(3.3)), test_xy("x * 1 == x" ,T(2.0),T(3.0),T(1.0)), test_xy("1 * x == x" ,T(2.0),T(3.0),T(1.0)), test_xy("y * 1 == y" ,T(2.0),T(3.0),T(1.0)), test_xy("1 * y == y" ,T(2.0),T(3.0),T(1.0)), test_xy("x * 0 == 0" ,T(2.0),T(3.0),T(1.0)), test_xy("0 * x == 0" ,T(2.0),T(3.0),T(1.0)), test_xy("y * 0 == 0" ,T(2.0),T(3.0),T(1.0)), test_xy("0 * y == 0" ,T(2.0),T(3.0),T(1.0)), test_xy("x + 1 == 1 + x",T(2.0),T(3.0),T(1.0)), test_xy("y + 1 == 1 + y",T(2.0),T(3.0),T(1.0)), test_xy("x + y == y + x",T(2.0),T(3.0),T(1.0)), test_xy("x * y == y * x",T(2.0),T(3.0),T(1.0)), test_xy("x < y" ,T(2.0),T(3.0),T(1.0)), test_xy("y > x" ,T(2.0),T(3.0),T(1.0)), test_xy("x <= y" ,T(2.0),T(3.0),T(1.0)), test_xy("y >= x" ,T(2.0),T(3.0),T(1.0)), test_xy("x + y > y" ,T(2.0),T(3.0),T(1.0)), test_xy("x + y > x" ,T(2.0),T(3.0),T(1.0)), test_xy("x * y > y" ,T(2.0),T(3.0),T(1.0)), test_xy("x * y > x" ,T(2.0),T(3.0),T(1.0)), test_xy("(x + y) > y" ,T(2.0),T(3.0),T(1.0)), test_xy("(x + y) > x" ,T(2.0),T(3.0),T(1.0)), test_xy("(x * y) > y" ,T(2.0),T(3.0),T(1.0)), test_xy("(x * y) > x" ,T(2.0),T(3.0),T(1.0)), test_xy("(2x + 3y) == (2*x + 3*y)" ,T(2.0),T(3.0),T(1.0)), test_xy("2(x + y) == (2*x + 2*y)" ,T(2.0),T(3.0),T(1.0)), test_xy(" (x + y)3 == (3*x + 3*y)" ,T(2.0),T(3.0),T(1.0)), test_xy("2x + 3y == 2*x + 3*y" ,T(2.0),T(3.0),T(1.0)), test_xy("2(x + y) == 2*x + 2*y" ,T(2.0),T(3.0),T(1.0)), test_xy(" (x + y)3 == 3*x + 3*y" ,T(2.0),T(3.0),T(1.0)), test_xy("equal(x+y^3/7,x+(y*y*y)/7)",T(2.0),T(3.0),T(1.0)), test_xy("equal(1-x^3+y^2*7,1-(x*x*x)+(y*y)*7)",T(2.0),T(3.0),T(1.0)), test_xy("equal( x^0,1)",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^1,x)",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^2,x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^3,x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^4,x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^5,x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^6,x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^7,x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^8,x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^9,x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^10,x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^11,x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^12,x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^13,x*x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^14,x*x*x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^15,x*x*x*x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^16,x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^17,x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^18,x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^19,x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^20,x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^21,x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^22,x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^23,x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^24,x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^25,x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x)",T(12.34),T(0.0),T(1.0)), test_xy("equal( y^0,1)",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^1,y)",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^2,y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^3,y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^4,y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^5,y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^6,y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^7,y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^8,y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^9,y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^10,y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^11,y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^12,y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^13,y*y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^14,y*y*y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^15,y*y*y*y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^16,y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^17,y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^18,y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^19,y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^20,y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^21,y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^22,y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^23,y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^24,y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^25,y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y)",T(0.0),T(12.34),T(1.0)), test_xy("equal( x^-0,1/1)",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^-1,1/(x))",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^-2,1/(x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^-3,1/(x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^-4,1/(x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^-5,1/(x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^-6,1/(x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^-7,1/(x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^-8,1/(x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal( x^-9,1/(x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-10,1/(x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-11,1/(x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-12,1/(x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-13,1/(x*x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-14,1/(x*x*x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-15,1/(x*x*x*x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-16,1/(x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-17,1/(x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-18,1/(x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-19,1/(x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-20,1/(x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-21,1/(x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-22,1/(x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-23,1/(x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-24,1/(x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal(x^-25,1/(x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x))",T(12.34),T(0.0),T(1.0)), test_xy("equal( y^-0,1/1)",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^-1,1/(y))",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^-2,1/(y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^-3,1/(y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^-4,1/(y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^-5,1/(y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^-6,1/(y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^-7,1/(y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^-8,1/(y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal( y^-9,1/(y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-10,1/(y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-11,1/(y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-12,1/(y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-13,1/(y*y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-14,1/(y*y*y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-15,1/(y*y*y*y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-16,1/(y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-17,1/(y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-18,1/(y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-19,1/(y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-20,1/(y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-21,1/(y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-22,1/(y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-23,1/(y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-24,1/(y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)), test_xy("equal(y^-25,1/(y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y*y))",T(0.0),T(12.34),T(1.0)) }; static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_xy); const std::size_t rounds = 1000; for (std::size_t r = 0; r < rounds; ++r) { for (std::size_t i = 0; i < test_list_size; ++i) { test_xy& test = const_cast&>(test_list[i]); exprtk::symbol_table symbol_table; symbol_table.add_variable("x",test.x); symbol_table.add_variable("y",test.y); exprtk::expression expression; expression.register_symbol_table(symbol_table); { exprtk::parser parser; if (!parser.compile(test.expr,expression)) { std::cout << "test_expression() - Error: " << parser.error() << "\tExpression: " << test.expr << std::endl; return false; } } T result = expression.value(); if (not_equal(result,test.result)) { printf("Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n", test.expr.c_str(), test.result, result); return false; } } } return true; } template struct test_ab { test_ab(std::string e, const std::string& v0, const std::string& v1, const T& r) : expr(e), a(v0), b(v1), c("ccc"), result(r) {} std::string expr; std::string a; std::string b; std::string c; T result; }; template inline bool run_test02() { static const test_ab test_list[] = { test_ab("'aaa' == 'aaa'" ,"","",T(1.0)), test_ab("'aaa' < 'bbb'" ,"","",T(1.0)), test_ab("'aaa' <= 'bbb'" ,"","",T(1.0)), test_ab("'bbb' > 'aaa'" ,"","",T(1.0)), test_ab("'bbb' >= 'aaa'" ,"","",T(1.0)), test_ab("'aaa' != 'aaa'" ,"","",T(0.0)), test_ab("'aaa' != 'bbb'" ,"","",T(1.0)), test_ab("'aaa' + '123' == 'aaa123'" ,"","",T(1.0)), test_ab("'aaa123' == 'aaa' + '123'" ,"","",T(1.0)), test_ab("('aaa' + '123') == 'aaa123'" ,"","",T(1.0)), test_ab("'aaa123' == ('aaa' + '123')" ,"","",T(1.0)), test_ab("'aaa' in 'aaa123'" ,"","",T(1.0)), test_ab("'123' in 'aaa123'" ,"","",T(1.0)), test_ab("'a123b' like '*123*'" ,"","",T(1.0)), test_ab("'a123b' like '*123?'" ,"","",T(1.0)), test_ab("'1XYZ2' ilike '*xyz*'" ,"","",T(1.0)), test_ab("'1XYZ2' ilike '*xyz?'" ,"","",T(1.0)), test_ab("inrange('aaa','bbb','ccc')" ,"","",T(1.0)), test_ab("a == b" ,"aaa","aaa",T(1.0)), test_ab("a != b" ,"aaa","bbb",T(1.0)), test_ab("a < b" ,"aaa","bbb",T(1.0)), test_ab("a <= b" ,"aaa","bbb",T(1.0)), test_ab("b > a" ,"aaa","bbb",T(1.0)), test_ab("b >= a" ,"aaa","bbb",T(1.0)), test_ab("a in b" ,"aaa","aaa123",T(1.0)), test_ab("a in b" ,"123","aaa123",T(1.0)), test_ab("a == 'aaa'" ,"aaa","aaa",T(1.0)), test_ab("'aaa' == a" ,"aaa","aaa",T(1.0)), test_ab("a != 'bbb'" ,"aaa","bbb",T(1.0)), test_ab("'bbb' != a" ,"aaa","bbb",T(1.0)), test_ab("a < 'bbb'" ,"aaa","bbb",T(1.0)), test_ab("a <= 'bbb'" ,"aaa","bbb",T(1.0)), test_ab("'bbb' > a" ,"aaa","bbb",T(1.0)), test_ab("'bbb' >= a" ,"aaa","bbb",T(1.0)), test_ab("a in 'aaa123'" ,"aaa","aaa123",T(1.0)), test_ab("a in 'aaa123'" ,"123","aaa123",T(1.0)), test_ab("'aaa' in b" ,"aaa","aaa123",T(1.0)), test_ab("'123' in b" ,"aaa","aaa123",T(1.0)), test_ab("(a < b) or (a == b)" ,"aaa","bbb",T(1.0)), test_ab("(a == b) or (a < b)" ,"aaa","bbb",T(1.0)), test_ab("(b > a) or (b == a)" ,"aaa","bbb",T(1.0)), test_ab("(b == a) or (b > a)" ,"aaa","bbb",T(1.0)), test_ab("(a < b) and (b > a)" ,"aaa","bbb",T(1.0)), test_ab("a like '*123*'" ,"a123b","",T(1.0)), test_ab("a like '*123?'" ,"a123b","",T(1.0)), test_ab("'a123b' like b" ,"a123b","*123*",T(1.0)), test_ab("'a123b' like b" ,"a123b","*123?",T(1.0)), test_ab("a ilike '*xyz*'" ,"1XYZ2","",T(1.0)), test_ab("a ilike '*xyz?'" ,"1XYZ2","",T(1.0)), test_ab("'1XYZ2' ilike b" ,"","*xyz*",T(1.0)), test_ab("'1XYZ2' ilike b" ,"","*xyz?",T(1.0)), test_ab("inrange(a,'bbb',c)" ,"aaa","bbb",T(1.0)), test_ab("inrange('aaa',b,'ccc')" ,"aaa","bbb",T(1.0)), test_ab("inrange(a,b,c)" ,"aaa","bbb",T(1.0)), test_ab("inrange(a,b,'ccc')" ,"aaa","bbb",T(1.0)), test_ab("inrange('aaa',b,c)" ,"aaa","bbb",T(1.0)), }; static const std::size_t test_list_size = sizeof(test_list) / sizeof(test_ab); const std::size_t rounds = 10000; for (std::size_t r = 0; r < rounds; ++r) { for (std::size_t i = 0; i < test_list_size; ++i) { test_ab& test = const_cast&>(test_list[i]); exprtk::symbol_table symbol_table; symbol_table.add_stringvar("a",test.a); symbol_table.add_stringvar("b",test.b); symbol_table.add_stringvar("c",test.c); exprtk::expression expression; expression.register_symbol_table(symbol_table); { exprtk::parser parser; if (!parser.compile(test.expr,expression)) { std::cout << "run_test02() - Error: " << parser.error() << "\tExpression: " << test.expr << std::endl; return false; } } T result = expression.value(); if (not_equal(result,test.result)) { printf("run_test02() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f\n", test.expr.c_str(), test.result, result); return false; } } } return true; } template inline bool run_test03() { std::string expression_string = "a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+w+x+y+z+" "A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z+" "aa+bb+cc+dd+ee+ff+gg+hh+ii+jj+kk+ll+mm+nn+oo+pp+qq+rr+ss+tt+uu+vv+ww+xx+yy+zz+" "AA+BB+CC+DD+EE+FF+GG+HH+II+JJ+KK+LL+MM+NN+OO+PP+QQ+RR+SS+TT+UU+VV+WW+XX+YY+ZZ+" "Aa+Bb+Cc+Dd+Ee+Ff+Gg+Hh+Ii+Jj+Kk+Ll+Mm+Nn+Oo+Pp+Qq+Rr+Ss+Tt+Uu+Vv+Ww+Xx+Yy+Zz+" "a0+b1+c2+d3+e4+f5+g6+h7+i8+j9+k0+l1+m2+n3+o4+p5+q6+r7+s8+t9+u0+v1+w2+x3+y4+z5+" "A0+B1+C2+D3+E4+F5+G6+H7+I8+J9+K0+L1+M2+N3+O4+P5+Q6+R7+S8+T9+U0+V1+W2+X3+Y4+Z5+" "aa0+bb1+cc2+dd3+ee4+ff5+gg6+hh7+ii8+jj9+kk0+ll1+mm2+nn3+oo4+pp5+qq6+rr7+ss8+tt9+uu0+vv1+ww2+xx3+yy4+zz5+" "AA0+BB1+CC2+DD3+EE4+FF5+GG6+HH7+II8+JJ9+KK0+LL1+MM2+NN3+OO4+PP5+QQ6+RR7+SS8+TT9+UU0+VV1+WW2+XX3+YY4+ZZ5+" "Aa0+Bb1+Cc2+Dd3+Ee4+Ff5+Gg6+Hh7+Ii8+Jj9+Kk0+Ll1+Mm2+Nn3+Oo4+Pp5+Qq6+Rr7+Ss8+Tt9+Uu0+Vv1+Ww2+Xx3+Yy4+Zz5"; static const std::string variable_list[] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "kk", "ll", "mm", "nn", "oo", "pp", "qq", "rr", "ss", "tt", "uu", "vv", "ww", "xx", "yy", "zz", "AA", "BB", "CC", "DD", "EE", "FF", "GG", "HH", "II", "JJ", "KK", "LL", "MM", "NN", "OO", "PP", "QQ", "RR", "SS", "TT", "UU", "VV", "WW", "XX", "YY", "ZZ", "Aa", "Bb", "Cc", "Dd", "Ee", "Ff", "Gg", "Hh", "Ii", "Jj", "Kk", "Ll", "Mm", "Nn", "Oo", "Pp", "Qq", "Rr", "Ss", "Tt", "Uu", "Vv", "Ww", "Xx", "Yy", "Zz", "a0", "b1", "c2", "d3", "e4", "f5", "g6", "h7", "i8", "j9", "k0", "l1", "m2", "n3", "o4", "p5", "q6", "r7", "s8", "t9", "u0", "v1", "w2", "x3", "y4", "z5", "A0", "B1", "C2", "D3", "E4", "F5", "G6", "H7", "I8", "J9", "K0", "L1", "M2", "N3", "O4", "P5", "Q6", "R7", "S8", "T9", "U0", "V1", "W2", "X3", "Y4", "Z5", "aa0", "bb1", "cc2", "dd3", "ee4", "ff5", "gg6", "hh7", "ii8", "jj9", "kk0", "ll1", "mm2", "nn3", "oo4", "pp5", "qq6", "rr7", "ss8", "tt9", "uu0", "vv1", "ww2", "xx3", "yy4", "zz5", "AA0", "BB1", "CC2", "DD3", "EE4", "FF5", "GG6", "HH7", "II8", "JJ9", "KK0", "LL1", "MM2", "NN3", "OO4", "PP5", "QQ6", "RR7", "SS8", "TT9", "UU0", "VV1", "WW2", "XX3", "YY4", "ZZ5", "Aa0", "Bb1", "Cc2", "Dd3", "Ee4", "Ff5", "Gg6", "Hh7", "Ii8", "Jj9", "Kk0", "Ll1", "Mm2", "Nn3", "Oo4", "Pp5", "Qq6", "Rr7", "Ss8", "Tt9", "Uu0", "Vv1", "Ww2", "Xx3", "Yy4", "Zz5" }; static const std::size_t variable_list_size = sizeof(variable_list) / sizeof(std::string); static const std::size_t rounds = 10000; for (std::size_t r = 0; r < rounds; ++r) { exprtk::symbol_table symbol_table; exprtk::expression expression; std::vector v; v.resize(variable_list_size); for (std::size_t i = 0; i < variable_list_size; ++i) { v[i] = i; symbol_table.add_variable(variable_list[i],v[i]); } symbol_table.add_constants(); expression.register_symbol_table(symbol_table); exprtk::parser parser; if (!parser.compile(expression_string,expression)) { std::cout << "run_test03() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } expression.value(); } return true; } template inline T clamp(const T& l, const T& v, const T& u) { return (v < l) ? l : ((v > u) ? u : v); } template inline bool run_test04() { std::string expression_string = "clamp(-1.0,sin(2 * pi * x) + cos(y / 2 * pi),+1.0)"; exprtk::symbol_table symbol_table; exprtk::expression expression; T x = T(-1000.0); T y = T(-1000.0); symbol_table.add_variable("x",x); symbol_table.add_variable("y",y); symbol_table.add_constants(); expression.register_symbol_table(symbol_table); { exprtk::parser parser; if (!parser.compile(expression_string,expression)) { std::cout << "run_test04() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } } const T pi = T(3.14159265358979323846); const T increment = T(0.0001); while ((x <= T(+1000.0)) && (y <= T(+1000.0))) { T result1 = expression.value(); T result2 = clamp(-1.0,std::sin(2 * pi * x) + std::cos(y / 2 * pi),+1.0); if (not_equal(result1,result2)) { printf("run_test04() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\n", expression_string.c_str(), result1, result2, x, y); return false; } x += increment; y += increment; } return true; } template inline bool run_test05() { typedef exprtk::expression expression_t; std::string expression_string = "clamp(-1.0,sin(2 * pi * x_var123) + cos(y_var123 / 2 * pi),+1.0)"; exprtk::symbol_table symbol_table; std::deque expression_list; T x = T(-1000.0); T y = T(-1000.0); symbol_table.add_variable("x_var123",x); symbol_table.add_variable("y_var123",y); symbol_table.add_constants(); const std::size_t expression_count = 100; for (std::size_t i = 0; i < expression_count; ++i) { expression_t e; exprtk::parser parser; e.register_symbol_table(symbol_table); if (!parser.compile(expression_string,e)) { std::cout << "run_test05() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } expression_list.push_back(e); } const T pi = T(3.14159265358979323846); const T increment = T(0.0001); while ((x <= T(+1000.0)) && (y <= T(+1000.0))) { T real_result = clamp(-1.0,std::sin(2 * pi * x) + std::cos(y / 2 * pi),+1.0); for (std::size_t i = 0; i < expression_list.size(); ++i) { expression_t& expr = expression_list[i]; T result = expr.value(); if (not_equal(result,real_result)) { printf("run_test05() - Computation Error: Expression: [%s]\tExpected: %19.15f\tResult: %19.15f x:%19.15f\ty:%19.15f\tIndex:%d\n", expression_string.c_str(), real_result, result, x, y, static_cast(i)); return false; } } x += increment; y += increment; } return true; } template inline bool run_test06() { typedef exprtk::expression expression_t; std::string expression_string = "sqrt(1 - (x^2))"; T x = T(0.0); exprtk::symbol_table symbol_table; symbol_table.add_variable("x",x); expression_t expression; expression.register_symbol_table(symbol_table); exprtk::parser parser; if (!parser.compile(expression_string,expression)) { std::cout << "run_test06() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } T total_area1 = exprtk::integrate(expression,x,T(-1.0),T(1.0)); T total_area2 = exprtk::integrate(expression,"x",T(-1.0),T(1.0)); const T pi = T(3.14159265358979323846); if (not_equal(total_area1,total_area2,0.000001)) { printf("run_test06() - Integration Error: area1 != area2\n"); return false; } if (not_equal(total_area1,pi/T(2.0),0.000001)) { printf("run_test06() - Integration Error: Expected: %19.15f\tResult: %19.15f\n", pi/T(2.0), total_area1); return false; } return true; } template inline bool run_test07() { typedef exprtk::expression expression_t; std::string expression_string = "sin(2x+1/3)"; T x = T(0.0); exprtk::symbol_table symbol_table; symbol_table.add_variable("x",x); expression_t expression; expression.register_symbol_table(symbol_table); exprtk::parser parser; if (!parser.compile(expression_string,expression)) { std::cout << "run_test07() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } for (x = -100.0; x < 100; x+=0.00001) { T result1 = exprtk::derivative(expression,x); T result2 = exprtk::derivative(expression,"x"); T real_result = T(2.0) * std::cos(T(2.0) * x + T(1.0/3.0)); if (not_equal(result1,result2,0.000000001)) { printf("run_test07() - Derivative Error: result1 != result2\n"); return false; } if (not_equal(result1,real_result,0.000000001)) { printf("run_test07() - Derivative Error: x: %19.15f\tExpected: %19.15f\tResult: %19.15f\n", x, real_result, result1); return false; } } return true; } template inline bool run_test08() { static const std::string expr_str[] = { "x", "y", "z", "w", "u", "x + y + z + w + u", "x + y / z * w ^ u", "x:=1.1", "y:=2.2", "z:=3.3", "w:=4.4", "u:=5.5", "x<-1.1", "y<-2.2", "z<-3.3", "w<-4.4", "u<-5.5", "x:=x+1.1", "y:=y+2.2", "z:=z+3.3", "w:=w+4.4", "u:=u+5.5", "x<-x+1.1", "y<-y+2.2", "z<-z+3.3", "w<-w+4.4", "u<-u+5.5", "x:=1.1+x", "y:=2.2+y", "z:=3.3+z", "w:=4.4+w", "u:=5.5+u", "x<-1.1+x", "y<-2.2+y", "z<-3.3+z", "w<-4.4+w", "u<-5.5+u", "x:=(x <= 1.1)", "y:=(2.2 >= y)", "z:=(3.3 and z)", "w:=(4.4 or w)", "u:=(u xor 5.5)", "x<-(x <= 1.1)", "y<-(2.2 >= y)", "z<-(3.3 and z)", "w<-(4.4 or w)", "u<-(u xor 5.5)", "min(x,y) + min(x,y,z) + min(x,y,z,w) + min(x,y,z,w,y)", "max(x,y) + max(x,y,z) + max(x,y,z,w) + max(x,y,z,w,y)", "avg(x,y)", "avg(x,y,z)", "avg(x,y,z,w)", "avg(x,y,z,w,u)", "(u := u <- min(x:=1,y:=2,z:=3)) == 1", "(2x+3y+4z+5w)==(2*x+3*y+4*z+5*w)", "(3(x+y)/2+1)==(3*(x+y)/2+1)", "((x+y)3+1/4)==((x+y)*3+1/4)", "((x+y)z+1/2)==((x+y)*z+1/2)", "(x+y^3/z) == (x+(y*y*y)/z)", "(z-x^3+y^2*7) == (z-(x*x*x)+(y*y)*7)", "(3min(x,y))==(3*min(x,y))", "(sin(x)y)==(sin(x)*y)", "(sin(x)cos(y)+1)==(sin(x)*cos(y)+1)", "(sgn(sin(x))cos(sgn(y))+1)==(sgn(sin(x))*cos(sgn(y))+1)", "equal($f00(x,y,z),((x+y)/z))", "equal($f01(x,y,z),((x+y)*z))", "equal($f02(x,y,z),((x-y)/z))", "equal($f03(x,y,z),((x-y)*z))", "equal($f04(x,y,z),((x*y)+z))", "equal($f05(x,y,z),((x*y)-z))", "equal($f06(x,y,z),((x*y)/z))", "equal($f07(x,y,z),((x*y)*z))", "equal($f08(x,y,z),((x/y)+z))", "equal($f09(x,y,z),((x/y)-z))", "equal($f10(x,y,z),((x/y)/z))", "equal($f11(x,y,z),((x/y)*z))", "equal($f12(x,y,z),(z/(x+y)))", "equal($f13(x,y,z),(z/(x-y)))", "equal($f14(x,y,z),(z/(x*y)))", "equal($f15(x,y,z),(z/(x/y)))", "equal($f16(x,y,z),(z-(x/y)))", "equal($f17(x,y,z),(z-(x/y)))", "equal($f18(x,y,z,w),(w+((x+y)/z)))", "equal($f19(x,y,z,w),(w+((x+y)*z)))", "equal($f20(x,y,z,w),(w+((x-y)/z)))", "equal($f21(x,y,z,w),(w+((x-y)*z)))", "equal($f22(x,y,z,w),(w+((x*y)/z)))", "equal($f23(x,y,z,w),(w+((x*y)*z)))", "equal($f24(x,y,z,w),(w+((x/y)+z)))", "equal($f25(x,y,z,w),(w+((x/y)/z)))", "equal($f26(x,y,z,w),(w+((x/y)*z)))", "equal($f27(x,y,z,w),(w-((x+y)/z)))", "equal($f28(x,y,z,w),(w-((x+y)*z)))", "equal($f29(x,y,z,w),(w-((x-y)/z)))", "equal($f30(x,y,z,w),(w-((x-y)*z)))", "equal($f31(x,y,z,w),(w-((x*y)/z)))", "equal($f32(x,y,z,w),(w-((x*y)*z)))", "equal($f33(x,y,z,w),(w-((x/y)/z)))", "equal($f34(x,y,z,w),(w-((x/y)*z)))", "equal($f35(x,y,z,w),(((x+y)*z)-w))", "equal($f36(x,y,z,w),(((x-y)*z)-w))", "equal($f37(x,y,z,w),(((x*y)*z)-w))", "equal($f38(x,y,z,w),(((x/y)*z)-w))", "equal($f39(x,y,z,w),(((x+y)/z)-w))", "equal($f40(x,y,z,w),(((x-y)/z)-w))", "equal($f41(x,y,z,w),(((x*y)/z)-w))", "equal($f42(x,y,z,w),(((x/y)/z)-w))", }; static const std::size_t expr_str_size = sizeof(expr_str) / sizeof(std::string); static const std::size_t rounds = 1000; for (std::size_t i = 0; i < rounds; ++i) { for (std::size_t j = 0; j < expr_str_size; ++j) { typedef exprtk::expression expression_t; T x = T(1.0); T y = T(2.0); T z = T(3.0); T w = T(4.0); T u = T(5.0); exprtk::symbol_table symbol_table; symbol_table.add_variable("x",x); symbol_table.add_variable("y",y); symbol_table.add_variable("z",z); symbol_table.add_variable("w",w); symbol_table.add_variable("u",u); expression_t expression; expression.register_symbol_table(symbol_table); exprtk::parser parser; if (!parser.compile(expr_str[j],expression)) { std::cout << "run_test08() - Error: " << parser.error() << "\tExpression: " << expr_str[j] << std::endl; return false; } expression.value(); } } return true; } template struct myfunc : public exprtk::ifunction { myfunc() : exprtk::ifunction(2) {} inline T operator()(const T& v1, const T& v2) { return T(1) + (v1 * v2) / T(3); } }; template inline bool run_test09() { static const std::size_t rounds = 100000; for (std::size_t i = 0; i < rounds; ++i) { typedef exprtk::expression expression_t; std::string expression_string = "myfunc0(sin(x*pi),y/2)+myfunc1(sin(x*pi),y/2)+" "myfunc2(sin(x*pi),y/2)+myfunc3(sin(x*pi),y/2)+" "myfunc4(sin(x*pi),y/2)+myfunc5(sin(x*pi),y/2)+" "myfunc6(sin(x*pi),y/2)+myfunc7(sin(x*pi),y/2)+" "myfunc8(sin(x*pi),y/2)+myfunc9(sin(x*pi),y/2)+" "myfunc0(sin(1*pi),y/2)+myfunc1(sin(1*pi),y/2)+" "myfunc2(sin(1*pi),y/2)+myfunc3(sin(1*pi),y/2)+" "myfunc4(sin(1*pi),y/2)+myfunc5(sin(1*pi),y/2)+" "myfunc6(sin(1*pi),y/2)+myfunc7(sin(1*pi),y/2)+" "myfunc8(sin(1*pi),y/2)+myfunc9(sin(1*pi),y/2)+" "myfunc0(sin(x*pi),2/2)+myfunc1(sin(x*pi),2/2)+" "myfunc2(sin(x*pi),2/2)+myfunc3(sin(x*pi),2/2)+" "myfunc4(sin(x*pi),2/2)+myfunc5(sin(x*pi),2/2)+" "myfunc6(sin(x*pi),2/2)+myfunc7(sin(x*pi),2/2)+" "myfunc8(sin(x*pi),2/2)+myfunc9(sin(x*pi),2/2)+" "myfunc0(sin(1*pi),2/2)+myfunc1(sin(1*pi),2/2)+" "myfunc2(sin(1*pi),2/2)+myfunc3(sin(1*pi),2/2)+" "myfunc4(sin(1*pi),2/2)+myfunc5(sin(1*pi),2/2)+" "myfunc6(sin(1*pi),2/2)+myfunc7(sin(1*pi),2/2)+" "myfunc8(sin(1*pi),2/2)+myfunc9(sin(1*pi),2/2)"; T x = T(1.0); T y = T(2.0); myfunc mf; exprtk::symbol_table symbol_table; symbol_table.add_variable("x",x); symbol_table.add_variable("y",y); symbol_table.add_function("myfunc0",mf); symbol_table.add_function("myfunc1",mf); symbol_table.add_function("myfunc2",mf); symbol_table.add_function("myfunc3",mf); symbol_table.add_function("myfunc4",mf); symbol_table.add_function("myfunc5",mf); symbol_table.add_function("myfunc6",mf); symbol_table.add_function("myfunc7",mf); symbol_table.add_function("myfunc8",mf); symbol_table.add_function("myfunc9",mf); symbol_table.add_constants(); expression_t expression; expression.register_symbol_table(symbol_table); exprtk::parser parser; if (!parser.compile(expression_string,expression)) { std::cout << "run_test09() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } const T pi = T(3.14159265358979323846); T result = expression.value(); T expected = T(4.0) * ( mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/2.0) + mf(sin(x*pi),y/2.0) ); if (not_equal(result,expected,0.0000001)) { printf("run_test09() - Error Expected: %19.15f\tResult: %19.15f\n", expected, result); return false; } } return true; } template inline bool run_test10() { T x = T(1.1); T y = T(2.2); T xx = T(3.3); T yy = T(4.4); std::string i = "A String"; std::string j = "Another String"; std::string ii = "A String"; std::string jj = "Another String"; exprtk::symbol_table symbol_table; typedef exprtk::expression expression_t; struct test { static inline bool variable(exprtk::symbol_table& symbol_table, const std::string& variable_name, const T& value) { exprtk::details::variable_node* var = symbol_table.get_variable(variable_name); if (var) return (!not_equal(var->ref(),value)); else return false; } static inline bool string(exprtk::symbol_table& symbol_table, const std::string& string_name, const std::string& str) { exprtk::details::stringvar_node* str_node = symbol_table.get_stringvar(string_name); if (str_node) return (str_node->ref() == str); else return false; } }; static const std::size_t rounds = 1000; for (std::size_t r = 0; r < rounds; ++r) { symbol_table.add_variable("x", x); symbol_table.add_variable("y", y); symbol_table.add_variable("xx",xx); symbol_table.add_variable("yy",yy); if (!symbol_table.symbol_exists("x")) { std::cout << "run_test10() - Symbol 'x' does not exist!\n"; return false; } else if (!symbol_table.symbol_exists("y")) { std::cout << "run_test10() - Symbol 'y' does not exist!\n"; return false; } else if (!symbol_table.symbol_exists("xx")) { std::cout << "run_test10() - Symbol 'xx' does not exist!\n"; return false; } else if (!symbol_table.symbol_exists("yy")) { std::cout << "run_test10() - Symbol 'yy' does not exist!\n"; return false; } else if (!test::variable(symbol_table,"x",x)) { std::cout << "run_test10() - Symbol 'x' value failure!\n"; return false; } else if (!test::variable(symbol_table,"y",y)) { std::cout << "run_test10() - Symbol 'y' value failure!\n"; return false; } else if (!test::variable(symbol_table,"xx",xx)) { std::cout << "run_test10() - Symbol 'xx' value failure!\n"; return false; } else if (!test::variable(symbol_table,"yy",yy)) { std::cout << "run_test10() - Symbol 'yy' value failure!\n"; return false; } if (!symbol_table.remove_variable("x")) { std::cout << "run_test10() - Failed to remove symbol 'x'!\n"; return false; } else if (!symbol_table.remove_variable("y")) { std::cout << "run_test10() - Failed to remove symbol 'y'!\n"; return false; } else if (!symbol_table.remove_variable("xx")) { std::cout << "run_test10() - Failed to remove symbol 'xx'!\n"; return false; } else if (!symbol_table.remove_variable("yy")) { std::cout << "run_test10() - Failed to remove symbol 'yy'!\n"; return false; } } for (std::size_t r = 0; r < rounds; ++r) { myfunc mf; symbol_table.add_function("f",mf); symbol_table.add_function("f1",mf); if (!symbol_table.symbol_exists("f")) { std::cout << "run_test10() - function 'f' does not exist!\n"; return false; } else if (!symbol_table.symbol_exists("f1")) { std::cout << "run_test10() - function 'f1' does not exist!\n"; return false; } if (!symbol_table.remove_function("f")) { std::cout << "run_test10() - Failed to remove function 'f'!\n"; return false; } else if (!symbol_table.remove_function("f1")) { std::cout << "run_test10() - Failed to remove function 'f1'!\n"; return false; } } for (std::size_t r = 0; r < rounds; ++r) { symbol_table.add_stringvar("i",i); symbol_table.add_stringvar("j",j); symbol_table.add_stringvar("ii",ii); symbol_table.add_stringvar("jj",jj); if (!symbol_table.symbol_exists("i")) { std::cout << "run_test10() - String 'i' does not exist!\n"; return false; } else if (!symbol_table.symbol_exists("j")) { std::cout << "run_test10() - String 'j' does not exist!\n"; return false; } else if (!symbol_table.symbol_exists("ii")) { std::cout << "run_test10() - String 'ii' does not exist!\n"; return false; } else if (!symbol_table.symbol_exists("jj")) { std::cout << "run_test10() - String 'jj' does not exist!\n"; return false; } else if (!test::string(symbol_table,"i",i)) { std::cout << "run_test10() - String 'i' value failure!\n"; return false; } else if (!test::string(symbol_table,"j",j)) { std::cout << "run_test10() - String 'j' value failure!\n"; return false; } else if (!test::string(symbol_table,"ii",ii)) { std::cout << "run_test10() - String 'ii' value failure!\n"; return false; } else if (!test::string(symbol_table,"jj",jj)) { std::cout << "run_test10() - String 'jj' value failure!\n"; return false; } else if (!symbol_table.remove_stringvar("i")) { std::cout << "run_test10() - Failed to remove String 'i'!\n"; return false; } else if (!symbol_table.remove_stringvar("j")) { std::cout << "run_test10() - Failed to remove String 'j'!\n"; return false; } else if (!symbol_table.remove_stringvar("ii")) { std::cout << "run_test10() - Failed to remove String 'ii'!\n"; return false; } else if (!symbol_table.remove_stringvar("jj")) { std::cout << "run_test10() - Failed to remove String 'jj'!\n"; return false; } } for (std::size_t r = 0; r < rounds; ++r) { symbol_table.add_variable("x", x); symbol_table.add_variable("y", y); symbol_table.add_variable("xx",xx); symbol_table.add_variable("yy",yy); std::vector expected_var_list; expected_var_list.push_back( "x"); expected_var_list.push_back( "y"); expected_var_list.push_back("xx"); expected_var_list.push_back("yy"); std::deque > variable_list; symbol_table.get_variable_list(variable_list); if (variable_list.size() != expected_var_list.size()) { std::cout << "run_test10() - Failed to get variable list (1)\n"; return false; } std::size_t found_count = 0; for (std::size_t i = 0; i < variable_list.size(); ++i) { for (std::size_t j = 0; j < expected_var_list.size(); ++j) { if (variable_list[i].first == expected_var_list[j]) { ++found_count; break; } } } if (found_count != expected_var_list.size()) { std::cout << "run_test10() - Failed to get variable list (2)\n"; return false; } } for (std::size_t r = 0; r < rounds; ++r) { symbol_table.add_variable("x", x); symbol_table.add_variable("y", y); symbol_table.add_variable("xx",xx); symbol_table.add_variable("yy",yy); std::vector expected_var_list; expected_var_list.push_back( "x"); expected_var_list.push_back( "y"); expected_var_list.push_back("xx"); expected_var_list.push_back("yy"); std::deque variable_list; symbol_table.get_variable_list(variable_list); if (variable_list.size() != expected_var_list.size()) { std::cout << "run_test10() - Failed to get variable list (3)\n"; return false; } std::size_t found_count = 0; for (std::size_t i = 0; i < variable_list.size(); ++i) { for (std::size_t j = 0; j < expected_var_list.size(); ++j) { if (variable_list[i] == expected_var_list[j]) { ++found_count; break; } } } if (found_count != expected_var_list.size()) { std::cout << "run_test10() - Failed to get variable list (4)\n"; return false; } } for (std::size_t r = 0; r < rounds; ++r) { symbol_table.add_stringvar( "i", i); symbol_table.add_stringvar( "j", j); symbol_table.add_stringvar("ii",ii); symbol_table.add_stringvar("jj",jj); std::vector expected_var_list; expected_var_list.push_back( "i"); expected_var_list.push_back( "j"); expected_var_list.push_back("ii"); expected_var_list.push_back("jj"); std::deque > stringvar_list; symbol_table.get_stringvar_list(stringvar_list); if (stringvar_list.size() != expected_var_list.size()) { std::cout << "run_test10() - Failed to get stringvar list (1)\n"; return false; } std::size_t found_count = 0; for (std::size_t i = 0; i < stringvar_list.size(); ++i) { for (std::size_t j = 0; j < expected_var_list.size(); ++j) { if (stringvar_list[i].first == expected_var_list[j]) { ++found_count; break; } } } if (found_count != expected_var_list.size()) { std::cout << "run_test10() - Failed to get stringvar list (2)\n"; return false; } } for (std::size_t r = 0; r < rounds; ++r) { symbol_table.add_stringvar("i", i); symbol_table.add_stringvar("j", j); symbol_table.add_stringvar("ii",ii); symbol_table.add_stringvar("jj",jj); std::vector expected_var_list; expected_var_list.push_back( "i"); expected_var_list.push_back( "j"); expected_var_list.push_back("ii"); expected_var_list.push_back("jj"); std::deque stringvar_list; symbol_table.get_stringvar_list(stringvar_list); if (stringvar_list.size() != expected_var_list.size()) { std::cout << "run_test10() - Failed to get stringvar list (3)\n"; return false; } std::size_t found_count = 0; for (std::size_t i = 0; i < stringvar_list.size(); ++i) { for (std::size_t j = 0; j < expected_var_list.size(); ++j) { if (stringvar_list[i] == expected_var_list[j]) { ++found_count; break; } } } if (found_count != expected_var_list.size()) { std::cout << "run_test10() - Failed to get stringvar list (4)\n"; return false; } } { T x0 = T(0); T y0 = T(0); T z0 = T(0); std::string expression_string = "(x0 + y0) / z0"; static const std::size_t rounds = 10000000; for (std::size_t i = 0; i < rounds; ++i) { expression_t expression0; x0 = T(i + 1.11); y0 = T(i + 2.22); z0 = T(i + 3.33); exprtk::symbol_table st0; st0.add_variable("x0",x0); st0.add_variable("y0",y0); st0.add_variable("z0",z0); expression0.register_symbol_table(st0); { exprtk::parser parser; if (!parser.compile(expression_string,expression0)) { std::cout << "run_test10() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } } { expression_t expression1; exprtk::symbol_table st1 = st0; expression1.register_symbol_table(st1); { exprtk::parser parser; if (!parser.compile(expression_string,expression1)) { std::cout << "run_test10() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } } st1.remove_variable("x0"); st1.remove_variable("y0"); st1.remove_variable("z0"); } } } return true; } template inline bool run_test11() { typedef exprtk::expression expression_t; std::string expression_string = "(x + y) / 3"; T x = T(1.0); T y = T(2.0); exprtk::symbol_table symbol_table; symbol_table.add_variable("x",x); symbol_table.add_variable("y",y); expression_t expression; expression.register_symbol_table(symbol_table); static const std::size_t rounds = 100000; for (std::size_t i = 0; i < rounds; ++i) { { exprtk::parser parser; if (!parser.compile(expression_string,expression)) { std::cout << "run_test11() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } } if (not_equal(expression.value(),(x + y)/T(3.0),0.000001)) { printf("run_test11() - Error in evaluation!(1)\n"); return false; } expression.release(); T result2 = expression.value(); if (result2 == result2) { printf("run_test11() - Error in evaluation!(2)\n"); return false; } { exprtk::parser parser; if (!parser.compile(expression_string,expression)) { std::cout << "run_test11() - Error: " << parser.error() << "\tExpression: " << expression_string << std::endl; return false; } } expression.value(); if (not_equal(expression.value(),(x + y)/T(3.0),0.000001)) { printf("run_test11() - Error in evaluation!(3)\n"); return false; } } if (!exprtk::pgo_primer()) { std::cout << "run_test11() - Failed PGO primer\n"; return false; } return true; } int main() { return ( run_test00() && run_test01() && run_test02() && run_test03() && run_test04() && run_test05() && run_test06() && run_test07() && run_test08() && run_test09() && run_test10() && run_test11() ) ? 0 : 1; }