From 8a4e81ef59c2055fa5e21bf4c6ea58296215aca9 Mon Sep 17 00:00:00 2001 From: Christophe de Dinechin Date: Sat, 27 Feb 2021 20:24:09 +0100 Subject: [PATCH] math: Implementation of the math module using more modern syntax The math module is one of the easiest modules to convert to the "new" syntax for module specifications. Functions there are lifted from `` on Linux. Presumably, the functions are generally available on all platforms. In the long run, it would be interesting to write all of them in XL, but for now it's mostly a waste of time. Signed-off-by: Christophe de Dinechin --- native/lib/xl.math.xl | 109 +++++++++---- native/lib/xl.math.xs | 141 ++++++++++------- src/builtins.xl | 19 +-- src/posix.cpp | 59 +++++-- tests/01.Evaluation/04-write-types.xl | 2 + tests/01.Evaluation/bug3327.ref | 2 +- tests/01.Evaluation/bug3327.xl | 4 +- tests/02.Arithmetic/07-math-functions.ref | 184 ++++++++++++++++++---- tests/02.Arithmetic/07-math-functions.xl | 53 +++++-- 9 files changed, 423 insertions(+), 150 deletions(-) diff --git a/native/lib/xl.math.xl b/native/lib/xl.math.xl index 357a90a9f..db15bb554 100644 --- a/native/lib/xl.math.xl +++ b/native/lib/xl.math.xl @@ -34,34 +34,89 @@ // If not, see . // ***************************************************************************** -MATH is -// ---------------------------------------------------------------------------- -// Implementation of the math module -// ---------------------------------------------------------------------------- +with + X:real + Y:real + Z:real + N:natural + I:integer + Base:real - // Basic math functions - abs X:integer as integer is builtin IAbs - abs X:real as real is builtin FAbs - sqrt X:real as real is C sqrt +// Generic implementation of abs and sign +generic_abs T is (if T < 0 then -T else T) +generic_sign T is (if T < 0 then -1 else if T > 0 then 1 else 0) - sin X:real as real is C sin - cos X:real as real is C cos - tan X:real as real is C tan - asin X:real as real is C asin - acos X:real as real is C acos - atan X:real as real is C atan - atan Y:real, X:real as real is C atan2 +abs I as integer is generic_abs I +sign I as integer is generic_sign I +abs X as real is generic_abs X +sign X as real is generic_sign X - sinh X:real as real is C sinh - cosh X:real as real is C cosh - tanh X:real as real is C tanh - asinh X:real as real is C asinh - acosh X:real as real is C acosh - atanh X:real as real is C atanh +// Nearest integer +ceil X as real is C "ceil" +floor X as real is C "floor" - exp X:real as real is C exp - expm1 X:real as real is C expm1 - log X:real as real is C log - log10 X:real as real is C log10 - log2 X:real as real is C log2 - log1p X:real as real is C log1p +// C interface for base functions +sqrt X as real is C "sqrt" +exp X as real is C "exp" +exp2 X as real is C "exp2" +log X as real is C "log" +ln X as real is log X +log10 X as real is C "log10" +log2 X as real is C "log2" +logb X as integer is C "logb" +log(Base,X) as real is (log X / log Base) +hypot(X,Y) as real is C "hypot" +cbrt X as real is C "cbrt" +erf X as real is C "erf" +lgamma X as real is C "lgamma" +fma X,Y,Z as real is C "fma" + +// Circular trigonometry +sin X as real is C "sin" +cos X as real is C "cos" +tan X as real is C "tan" +asin X as real is C "asin" +acos X as real is C "acos" +atan X as real is C "atan" +atan Y/X as real is C "atan2" + +// Hyperbolic trigonometry +sinh X as real is C "sinh" +cosh X as real is C "cosh" +tanh X as real is C "tanh" +asinh X as real is C "asinh" +acosh X as real is C "acosh" +atanh X as real is C "atanh" + +// Bessel functions +j0 X as real is C "j0" +j1 X as real is C "j1" +jn I, X as real is C "jn" +y0 X as real is C "y0" +y1 X as real is C "y1" +yn I, X as real is C "yn" + +// Optimized forms +(exp X)-1.0 as real is C "expm1" +log (1.0+X) as real is C "log1p" +log (X+1.0) as real is C "log1p" +2.0^X as real is C "exp2" + +// Constants +pi is 3.1415926535897932384626433 +e is 2.7182818284590452353602875 + +// Optimized expressions +// constant (log2 [[e]]) is 1.442695040888963407359924681001892137 +// constant (log10 [[e]]) is 0.434294481903251827651128918916605082 +// constant (log 2.0) is 0.693147180559945309417232121458176568 +// constant (pi/2.0) is 1.570796326794896619231321691639751442 +// constant (pi/4.0) is 0.785398163397448309615660845819875721 +// constant (pi*0.5) is constant(pi/2.0) +// constant (pi*0.25) is constant(pi/4.0) +// constant (1.0/[[pi]]) is 0.318309886183790671537767526745028724 +// constant (2.0/[[pi]]) is 0.636619772367581343075535053490057448 +// constant (2.0/sqrt [[pi]]) is 1.128379167095512573896158903121545172 +// constant (sqrt 2.0) is 1.414213562373095048801688724209698079 +// constant (1.0/sqrt 2.0) is 0.707106781186547524400844362104849039 +// constant (sqrt 2.0/2.0) is 0.707106781186547524400844362104849039 diff --git a/native/lib/xl.math.xs b/native/lib/xl.math.xs index 4f92c17ea..4413c9e61 100644 --- a/native/lib/xl.math.xs +++ b/native/lib/xl.math.xs @@ -34,64 +34,99 @@ // If not, see . // ***************************************************************************** -module ARBITRARY_PRECISION +with + X:real + Y:real + Z:real + N:natural + I:integer + Base:real -module COMPLEX -module QUATERNION -module VECTOR -module MATRIX -module STATISTICS +// Functions on integer values +abs I as integer +sign I as integer +// Functions on real values +abs X as real +sign X as real +ceil X as real +floor X as real +sqrt X as real +exp X as real +exp2 X as real +log X as real +ln X as real +log10 X as real +log2 X as real +logb X as integer +log(Base,X) as real +hypot(X,Y) as real +hypothenuse(X,Y)as real is hypot(X,Y) +cbrt X as real +CubeRoot X as real is cbrt X +erf X as real +ErrorFunction X as real is erf X +lgamma X as real +LogGamma X as real is lgamma X +fma X,Y,Z as real +X*Y+Z as real is fma X,Y,Z +Z+X*Y as real is fma X,Y,Z -// Using the `MATH` module by default uses `real` functions and constants -use REAL -use MATH[real].FUNCTIONS -use MATH[real].CONSTANTS +// Circular trigonometry +sin X as real +cos X as real +tan X as real +asin X as real +acos X as real +atan X as real +atan Y/X as real +// Hyperbolic trigonometry +sinh X as real +cosh X as real +tanh X as real +asinh X as real +acosh X as real +atanh X as real -module MATH[type number] with -// ---------------------------------------------------------------------------- -// Interface of the math module for a given number type -// ---------------------------------------------------------------------------- +// Bessel functions +j0 X as real +j1 X as real +jn I, X as real +J 0, X as real is j0 X +J 1, X as real is j1 X +J I, X as real is jn I,X +y0 X as real +y1 X as real +yn I, X as real +Y 0, X as real is y0 X +Y 1, X as real is y1 X +Y I, X as real is yn I, X - module FUNCTIONS with - // ------------------------------------------------------------------------ - // Interface for basic math functions - // ------------------------------------------------------------------------ +// Optimized forms +(exp X) - 1.0 as real +log (1.0+X) as real +log (X+1.0) as real +2.0^X as real - Abs X:number as number - Sign X:number as integer - Sqrt X:number as number +// Constants +pi +e - Sin X:number as number - Cos X:number as number - Tan X:number as number - ArcSin X:number as number - ArcCos X:number as number - ArcTan X:number as number - ArcTan Y:number, X:number as number - - SinH X:number as number - CosH X:number as number - TanH X:number as number - ArcSinH X:number as number - ArcCosH X:number as number - ArcTanH X:number as number - - Exp X:number as number - Exp X:number - 1 as number - Log X:number as number - Log10 X:number as number - Log2 X:number as number - Log2i X:number as integer - Log (1 + X:number) as number - - - module CONSTANTS is - // ------------------------------------------------------------------------ - // Interface for math constants - // ------------------------------------------------------------------------ - ZERO is number 0 - ONE is number 1 - TWO is number 2 - PI is number 3.1415926535897932384626433 +// Optimized expressions +// constant (log2 [[e]]) +// constant (log10 [[e]]) +// constant (log 2.0) +// constant (pi/2.0) +// constant (pi/4.0) +// constant (pi*0.5) +// constant (pi*0.25) +// constant (1.0/[[pi]]) +// constant (2.0/[[pi]]) +// constant (2.0/sqrt [[pi]]) +// constant (1.0/[[pi]]) +// constant (2.0/[[pi]]) +// constant (2.0/sqrt [[pi]]) +// constant (sqrt 2.0) +// constant (1.0/sqrt 2.0) +// constant (sqrt 2.0/2.0) diff --git a/src/builtins.xl b/src/builtins.xl index 8ec6de8e1..ba549b507 100644 --- a/src/builtins.xl +++ b/src/builtins.xl @@ -150,23 +150,8 @@ Source:text from First:natural as text is text_range(Source, First, not 0) parse Source:text is C "xl_parse_text" // Basic math functions -abs X is if X < 0 then -X else X -pi is 3.1415926535897932384626433 -sin X:real as real is C "sin" -cos X:real as real is C "cos" -tan X:real as real is C "tan" -asin X:real as real is C "asin" -acos X:real as real is C "acos" -atan X:real as real is C "atan" -exp X:real as real is C "exp" -exp2 X:real as real is C "exp2" -expm1 X:real as real is C "expm1" -log X:real as real is C "log" -log2 X:real as real is C "log2" -log10 X:real as real is C "log10" -log1p X:real as real is C "log1p" -sqrt X:real as real is C "sqrt" -atan Y:real / X:real as real is C "atan2" +abs X is if X < 0 then -X else X +sign X is if X < 0 then -1 else if X > 0 then 1 else 0 // If-then-else statement if [[true]] then True else False is True diff --git a/src/posix.cpp b/src/posix.cpp index 6b121e519..e2772d240 100644 --- a/src/posix.cpp +++ b/src/posix.cpp @@ -71,21 +71,62 @@ double fn(double x, double y) \ NATIVE(fn); \ } -MATH(sin); -MATH(cos); -MATH(tan); -MATH(asin); -MATH(acos); -MATH(atan); +#define MATH2I(fn) \ +namespace \ +{ \ +double fn(int x, double y) \ +{ \ + return ::fn(x, y); \ +} \ +NATIVE(fn); \ +} + +#define MATH3(fn) \ +namespace \ +{ \ +double fn(double x, double y, double z) \ +{ \ + return ::fn(x, y, z); \ +} \ +NATIVE(fn); \ +} + +MATH(ceil); +MATH(floor); +MATH(sqrt); MATH(exp); -MATH(expm1); MATH(exp2); +MATH(expm1); MATH(log); MATH(log2); MATH(log10); MATH(log1p); -MATH(sqrt); -MATH2(atan2); +MATH(logb); +MATH2(hypot); +MATH(cbrt); +MATH(erf); +MATH(lgamma); +MATH3(fma); MATH2(pow); +MATH(sin); +MATH(cos); +MATH(tan); +MATH(asin); +MATH(acos); +MATH(atan); +MATH2(atan2); +MATH(sinh); +MATH(cosh); +MATH(tanh); +MATH(asinh); +MATH(acosh); +MATH(atanh); +MATH(j0); +MATH(j1); +MATH2I(jn); +MATH(y0); +MATH(y1); +MATH2I(yn); + XL_END diff --git a/tests/01.Evaluation/04-write-types.xl b/tests/01.Evaluation/04-write-types.xl index d61592355..494b3a3cd 100644 --- a/tests/01.Evaluation/04-write-types.xl +++ b/tests/01.Evaluation/04-write-types.xl @@ -31,6 +31,8 @@ // along with XL, in a file named COPYING. // If not, see . // ***************************************************************************** +import XL.MATH + print "Hello" print 'C' print 12 diff --git a/tests/01.Evaluation/bug3327.ref b/tests/01.Evaluation/bug3327.ref index 8cb66c37c..aff798cf2 100644 --- a/tests/01.Evaluation/bug3327.ref +++ b/tests/01.Evaluation/bug3327.ref @@ -1 +1 @@ -23.1407 +8.53973 diff --git a/tests/01.Evaluation/bug3327.xl b/tests/01.Evaluation/bug3327.xl index 9658b468d..1ee1d96ee 100644 --- a/tests/01.Evaluation/bug3327.xl +++ b/tests/01.Evaluation/bug3327.xl @@ -31,4 +31,6 @@ // along with XL, in a file named COPYING. // If not, see . // ***************************************************************************** -exp(1) * pi +import XL.MATH + +pi * exp(1) diff --git a/tests/02.Arithmetic/07-math-functions.ref b/tests/02.Arithmetic/07-math-functions.ref index 079515cf6..cad95f896 100644 --- a/tests/02.Arithmetic/07-math-functions.ref +++ b/tests/02.Arithmetic/07-math-functions.ref @@ -1,61 +1,181 @@ +--- Running tests with 1.13331e-07 --- +abs 1.13331e-07=1.13331e-07 +sign 1.13331e-07=1 +ceil 1.13331e-07=1 +floor 1.13331e-07=0 +sqrt 1.13331e-07=0.000336647 +exp 1.13331e-07=1 +exp2 1.13331e-07=1 +expm1 1.13331e-07=1.13331e-07 +log 1.13331e-07=-15.993 +log10 1.13331e-07=-6.94565=-6.94565 +log2 1.13331e-07=-23.073 +log1p 1.13331e-07=1.13331e-07=1.13331e-07 +hypot 1.13331e-07=1=1 +cbrt 1.13331e-07=0.0048393=0.0048393 +erf 1.13331e-07=1.2788e-07=1.2788e-07 +lgamma 1.13331e-07=15.993=15.993 +fma 1.13331e-07=2=2 +0.25+sin 1.13331e-07=0.25 +0.25+cos 1.13331e-07=1.25 +0.25+tan 1.13331e-07=0.25 +asin 1.13331e-07=1.13331e-07 +acos 1.13331e-07=1.5708 +atan 1.13331e-07=1.13331e-07 +0.25+sinh 1.13331e-07=0.25 +0.25+cosh 1.13331e-07=1.25 +0.25+tanh 1.13331e-07=0.25 +asinh 1.13331e-07=1.13331e-07 +acosh 1.13331e-07=nan +atanh 1.13331e-07=1.13331e-07 +j0 1.13331e-07=1=1 +j1 1.13331e-07=5.66655e-08=5.66655e-08 +j3 1.13331e-07=3.03253e-23=3.03253e-23 +y0 1.13331e-07=-10.2552=-10.2552 +y1 1.13331e-07=-5.61735e+06=-5.61735e+06 +y3 1.13331e-07=-3.49884e+21=-3.49884e+21 --- Running tests with 0.13331 --- abs 0.13331=0.13331 +sign 0.13331=1 +ceil 0.13331=1 +floor 0.13331=0 sqrt 0.13331=0.365116 -sin 0.13331=0.382915 -cos 0.13331=1.24113 -tan 0.13331=0.384105 -asin 0.13331=0.133708 -acos 0.13331=1.43709 -atan 0.13331=0.132529 exp 0.13331=1.1426 +exp2 0.13331=1.09681 expm1 0.13331=0.142604 log 0.13331=-2.01508 -log10 0.13331=-0.875137 +log10 0.13331=-0.875137=-0.875137 log2 0.13331=-2.90714 -log1p 0.13331=0.125143 +log1p 0.13331=0.125143=0.125143 +hypot 0.13331=1.14112=1.14112 +cbrt 0.13331=0.510843=0.510843 +erf 0.13331=0.149538=0.149538 +lgamma 0.13331=1.95187=1.95187 +fma 0.13331=2.28439=2.28439 +0.25+sin 0.13331=0.382915 +0.25+cos 0.13331=1.24113 +0.25+tan 0.13331=0.384105 +asin 0.13331=0.133708 +acos 0.13331=1.43709 +atan 0.13331=0.132529 +0.25+sinh 0.13331=0.383705 +0.25+cosh 0.13331=1.2589 +0.25+tanh 0.13331=0.382526 +asinh 0.13331=0.132918 +acosh 0.13331=nan +atanh 0.13331=0.134108 +j0 0.13331=0.995562=0.995562 +j1 0.13331=0.066507=0.066507 +j3 0.13331=4.9302e-05=4.9302e-05 +y0 0.13331=-1.3478=-1.3478 +y1 0.13331=-4.88681=-4.88681 +y3 0.13331=-2154.51=-2154.51 --- Running tests with 1.3331 --- abs 1.3331=1.3331 +sign 1.3331=1 +ceil 1.3331=2 +floor 1.3331=1 sqrt 1.3331=1.1546 -sin 1.3331=1.22188 -cos 1.3331=0.485464 -tan 1.3331=4.37752 -asin 1.3331=nan -acos 1.3331=nan -atan 1.3331=0.927211 exp 1.3331=3.79278 +exp2 1.3331=2.51943 expm1 1.3331=2.79278 log 1.3331=0.287507 -log10 1.3331=0.124863 +log10 1.3331=0.124863=0.124863 log2 1.3331=0.414785 -log1p 1.3331=0.847198 +log1p 1.3331=0.847198=0.847198 +hypot 1.3331=2.6871=2.6871 +cbrt 1.3331=1.10058=1.10058 +erf 1.3331=0.940609=0.940609 +lgamma 1.3331=-0.113161=-0.113161 +fma 1.3331=6.44336=6.44336 +0.25+sin 1.3331=1.22188 +0.25+cos 1.3331=0.485464 +0.25+tan 1.3331=4.37752 +asin 1.3331=nan +acos 1.3331=nan +atan 1.3331=0.927211 +0.25+sinh 1.3331=2.01456 +0.25+cosh 1.3331=2.27822 +0.25+tanh 1.3331=1.12 +asinh 1.3331=1.09847 +acosh 1.3331=0.795101 +atanh 1.3331=nan +j0 1.3331=0.60269=0.60269 +j1 1.3331=0.529047=0.529047 +j3 1.3331=0.0441123=0.0441123 +y0 1.3331=0.304305=0.304305 +y1 1.3331=-0.52524=-0.52524 +y3 1.3331=-2.75224=-2.75224 --- Running tests with 3.14159 --- abs 3.14159=3.14159 +sign 3.14159=1 +ceil 3.14159=4 +floor 3.14159=3 sqrt 3.14159=1.77245 -sin 3.14159=0.25 -cos 3.14159=-0.75 -tan 3.14159=0.25 -asin 3.14159=nan -acos 3.14159=nan -atan 3.14159=1.26263 exp 3.14159=23.1407 +exp2 3.14159=8.82498 expm1 3.14159=22.1407 log 3.14159=1.14473 -log10 3.14159=0.49715 +log10 3.14159=0.49715=0.49715 log2 3.14159=1.6515 -log1p 3.14159=1.42108 +log1p 3.14159=1.42108=1.42108 +hypot 3.14159=5.19831=5.19831 +cbrt 3.14159=1.46459=1.46459 +erf 3.14159=0.999991=0.999991 +lgamma 3.14159=0.827695=0.827695 +fma 3.14159=18.1528=18.1528 +0.25+sin 3.14159=0.25 +0.25+cos 3.14159=-0.75 +0.25+tan 3.14159=0.25 +asin 3.14159=nan +acos 3.14159=nan +atan 3.14159=1.26263 +0.25+sinh 3.14159=11.7987 +0.25+cosh 3.14159=11.842 +0.25+tanh 3.14159=1.24627 +asinh 3.14159=1.8623 +acosh 3.14159=1.81153 +atanh 3.14159=nan +j0 3.14159=-0.304242=-0.304242 +j1 3.14159=0.284615=0.284615 +j3 3.14159=0.333458=0.333458 +y0 3.14159=0.328366=0.328366 +y1 3.14159=0.358873=0.358873 +y3 3.14159=-0.48607=-0.48607 --- Running tests with 6.28319 --- abs 6.28319=6.28319 +sign 6.28319=1 +ceil 6.28319=7 +floor 6.28319=6 sqrt 6.28319=2.50663 -sin 6.28319=0.25 -cos 6.28319=1.25 -tan 6.28319=0.25 -asin 6.28319=nan -acos 6.28319=nan -atan 6.28319=1.41297 exp 6.28319=535.492 +exp2 6.28319=77.8802 expm1 6.28319=534.492 log 6.28319=1.83788 -log10 6.28319=0.79818 +log10 6.28319=0.79818=0.79818 log2 6.28319=2.6515 -log1p 6.28319=1.98557 +log1p 6.28319=1.98557=1.98557 +hypot 6.28319=9.6189=9.6189 +cbrt 6.28319=1.84527=1.84527 +erf 6.28319=1=1 +lgamma 6.28319=5.27779=5.27779 +fma 6.28319=54.0448=54.0448 +0.25+sin 6.28319=0.25 +0.25+cos 6.28319=1.25 +0.25+tan 6.28319=0.25 +asin 6.28319=nan +acos 6.28319=nan +atan 6.28319=1.41297 +0.25+sinh 6.28319=267.995 +0.25+cosh 6.28319=267.997 +0.25+tanh 6.28319=1.24999 +asinh 6.28319=2.5373 +acosh 6.28319=2.52463 +atanh 6.28319=nan +j0 6.28319=0.220277=0.220277 +j1 6.28319=-0.212383=-0.212383 +j3 6.28319=0.0291122=0.0291122 +y0 6.28319=-0.229109=-0.229109 +y1 6.28319=-0.239074=-0.239074 +y3 6.28319=0.336483=0.336483 true diff --git a/tests/02.Arithmetic/07-math-functions.xl b/tests/02.Arithmetic/07-math-functions.xl index e7a972941..e5cfad679 100644 --- a/tests/02.Arithmetic/07-math-functions.xl +++ b/tests/02.Arithmetic/07-math-functions.xl @@ -31,25 +31,58 @@ // along with XL, in a file named COPYING. // If not, see . // ***************************************************************************** + +import XL.MATH + run_test x is print "--- Running tests with ", x, " ---" print "abs ", x, "=", abs x + print "sign ", x, "=", sign x + + print "ceil ", x, "=", ceil x + print "floor ", x, "=", floor x print "sqrt ", x, "=", sqrt x - // Avoid platform-dependent rounding errors for very small values - print "sin ", x, "=", 0.25 + sin x - print "cos ", x, "=", 0.25 + cos x - print "tan ", x, "=", 0.25 + tan x - print "asin ", x, "=", asin x - print "acos ", x, "=", acos x - print "atan ", x, "=", atan x + print "exp ", x, "=", exp x - print "expm1 ", x, "=", expm1 x + print "exp2 ", x, "=", exp2 x + print "expm1 ", x, "=", exp x - 1 print "log ", x, "=", log x - print "log10 ", x, "=", log10 x + print "log10 ", x, "=", log10 x, "=", log(10,x) print "log2 ", x, "=", log2 x - print "log1p ", x, "=", log1p x + print "log1p ", x, "=", log(1+x), "=", log(x+1) + + print "hypot ", x, "=", hypot(x, x+1), "=", hypothenuse(x, x+1) + print "cbrt ", x, "=", cbrt(x), "=", CubeRoot(x) + print "erf ", x, "=", erf(x), "=", ErrorFunction(x) + print "lgamma ", x, "=", lgamma(x), "=", LogGamma(x) + print "fma ", x, "=", fma(x, x+1, x+2), "=", x * (x+1) + (x+2) + + // Trig functions - Avoid platform-dependent rounding for small values + print "0.25+sin ", x, "=", 0.25 + sin x + print "0.25+cos ", x, "=", 0.25 + cos x + print "0.25+tan ", x, "=", 0.25 + tan x + print "asin ", x, "=", asin x + print "acos ", x, "=", acos x + print "atan ", x, "=", atan x + + // Hyperbolic functions + print "0.25+sinh ", x, "=", 0.25 + sinh x + print "0.25+cosh ", x, "=", 0.25 + cosh x + print "0.25+tanh ", x, "=", 0.25 + tanh x + print "asinh ", x, "=", asinh x + print "acosh ", x, "=", acosh x + print "atanh ", x, "=", atanh x + + // Bessel functions + print "j0 ", x, "=", j0(x), "=", j(0,x) + print "j1 ", x, "=", j1(x), "=", j(1,x) + print "j3 ", x, "=", jn(3, x), "=", j(3, x) + print "y0 ", x, "=", y0(x), "=", y(0,x) + print "y1 ", x, "=", y1(x), "=", y(1,x) + print "y3 ", x, "=", yn(3, x), "=", y(3, x) +run_test 1.13331e-7 run_test 0.13331 run_test 1.3331 run_test pi