Closed johnnyontheweb closed 1 year ago
Hi,
This has been broadly discussed years ago. The mathematically correct order is as specified in Wikipedia:
-3^2 = -9
and 2^3^3 = 2^(3^3) = 2^27
and not -3^2 = 9
or (2^3)^3 = 8^3
.
I know that Excel works differently. In the early versions of Calcpad, we made it exactly as in Excel for compatibility. However, this was well explained and documented. And still it is: https://calcpad.eu/help/21/operators
Years ago, after a long discussion, we changed it to match the commonly accepted mathematical rules. Wolfram Alpha also calculates like this: -2^2 2^3^3
About the discussion, you are generally right. Also, I definitely disagree with four things:
-u
" is not the "sign of u
". This is a unary operator. If we have 0 - u
, then it is a binary operator.x^y
is not "x
" multiplied "y
" times: "-2^2 is (-2 * -2)". This is just a special case, where "y
" is a natural number. But what about x^1.5
or x^pi
or x^z
, where z
is a complex number.x^y
operator (and for any C-like language that applies). Instead, it uses the Math.Pow(x, y)
function, which is quite different. However, in VB.NET, which has this operator, -2^2 = -4
.However, for such niche specific languages like Calcpad, Excel or Jace, it is possible to have their specific syntax that may differ from the common math notation, which obviously is the case for Excel. It should not be a problem as long as it is well documented and known.
BTW, you can use Calcpad as a C# library to parse expressions in the same way as Jace. You have to reference the Calcpad.Core project. You can check the source code of the Command line interpreter:
https://github.com/Proektsoftbg/Calcpad/blob/main/Calcpad.Cli/Program.cs
Thanks a lot for the explanation!
BTW, I used the benchmark project from this blog post to test Calcpad versus Jace and NCalc.
First, I upgraded the project to the latest .NET 7.0. Otherwise, I would not be able to use it with Calcpad. Then, installed Jace and NCalc packages from Nuget and also referenced Calcpad.Core.dll. I added a test method similar to others but for Calcpad:
private static void BenchmarkCalcpad(IEnumerable<string> formulas)
{
DateTime startTime = DateTime.Now;
var parser = new MathParser(new MathSettings());
foreach (string formula in formulas)
{
parser.Parse(formula);
for (int i = 0; i < NumberOfTests; i++)
{
parser.SetVariable("var1", NextDouble());
parser.SetVariable("var2", NextDouble());
parser.SetVariable("var3", NextDouble());
double resultCalcpad = parser.CalculateReal();
}
}
DateTime endTime = DateTime.Now;
Console.WriteLine("Execution time Calcpad: {0}", endTime - startTime);
}
Finally, I compiled the code to release and run the app from the "\bin\Release\" folder.
On my machine, I got the following results:
The upgraded benchmark project can be downloaded from here: CalcBenchmark.zip
Jace looks very professional and also NCalc. Although Calcpad was not designed as a .NET library, it performed 2-3 times faster. :)
Wow, it looks very good - I should definitely try CalcPad as interpreter for my scripts. I have to say that this test seems to contradict what's showed in this blog post (it seems Jace became slower than Ncalc, at least on .NET 7). Thanks also for sharing the code. However, to let me use CalcPad for my scripts, I need the support for custom functions (ex. MyFunction(x,y)).
Actually, you can use functions and other advanced Calcpad features: units, numerical methods, etc.
parser.Parse("f(x)=x^2");
parser.Calculate();
Then, you can use it further:
parser.Parse("f(1)");
parser.Calculate();
Thanks, but I need something more complex, e.g. I want to write the code for the function (also to interact with other data and other existing libraries of mine), this is not as simple as defining f(x)=...
If it is a very complex function, you can write it directly in C#. It will still read and write Calcpad variables and interact with whatever else you need.
If you need to keep your code in strings and execute it dynamically, use the Roslin Scripting API: https://github.com/dotnet/roslyn/blob/main/docs/wiki/Scripting-API-Samples.md
It is the most native and powerful way to compile and execute C# code at runtime. I do not think we can do something better about that. First, you need to install the package:
Install-Package Microsoft.CodeAnalysis.CSharp.Scripting
Then, add a using clause and... use it:
using Microsoft.CodeAnalysis.CSharp.Scripting;
double result = await CSharpScript.EvaluateAsync<double>("1d + 2d");
Explore the samples from the above link to learn more. It is very well explained. :)
Thanks for the hint, however the code in functions cannot be scripted (just for clarity: I have compiled functions, not to be scripted). I need something like https://github.com/pieterderycke/Jace/wiki/Custom-Functions
OK. I see. We can add such feature if we decide in future to make Calcpad a .NET library.
Hello, see this other issue of an external library : https://github.com/pieterderycke/Jace/issues/79 in which CalcPad is cited for comparison. I believe CalcPad assumes the correct operations order. On the other hand, Excel gives different results for the same formulas (see linked issue), mainly because the minus sign before u is not evaluated in operations order. Please find attached excel file. test.xlsx
I need to clarify this - thanks in advance