perrytaylor
asked on
Order of Operations for custom operators
At my request some of the experts came up w/ a class that replicated a double data type except it has an operator ^ that replaces math.pow(). This works wonderfully except that in long calculations it executes at the same order as + or -. Is there a way to set the order of operations of a custom operator so that the power will execute before the multiplication or addition?
public struct Double
{
public double value;
public Double(double d)
{
value = d;
}
public Double(Double D)
{
value = D.value;
}
public static double operator ^(Double A, Double B)
{
Double C = new Double();
C = Math.Pow(A.value, B.value);
return C;
}
public static double operator ^(Double A, double B)
{
Double C = new Double();
C= Math.Pow(A.value, B);
return C;
}
public static double operator ^(Double A, int B)
{
return Math.Pow(A.value, B);
}
public static double operator ^(double A, Double B)
{
return Math.Pow(A, B.value);
}
public static implicit operator Double(double d)
{
return fromdouble(d);
}
public static implicit operator double(Double D)
{
return fromDouble(D);
}
public static double fromDouble(Double D)
{
return D.value;
}
public static Double fromdouble(double d)
{
return new Double(d);
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
In light of my last comment, the only suitable override that I can think of is actually the index operator. Which cannot be overloaded, but there's a "trick" which you can use: indexers, to achieve the same goal.
But would that be a good thing to do? Redefining ^ is one thing (because it is little used, there's not too much danger to say that "what used to be a logical or, is now a power operator"), but saying that [] means power is another.
Consider this:
But would that be a good thing to do? Redefining ^ is one thing (because it is little used, there's not too much danger to say that "what used to be a logical or, is now a power operator"), but saying that [] means power is another.
Consider this:
// current
Double d1, d2, d3;
Double result = d1 ^ (d2 ^ d3); // without the bracket it would evaluate (d1 ^ d2) ^ d3
//or the only alternative I can think of:
Double d1, d2, d3;
Double result = d1[d2[d3]]; // no extra brackets needed, but is it clearer?
Ah, forgot to add the reference to my quotes, apologies: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf
ASKER
I guess this begs the question then what should I do for a couple of equations that are over 5,000 characters long w/ about 500 ^ in them? Is there any way to get around manually going in there and putting Math.Pow() in place of ^?
Yes, you can, of course. What about using something totally off-limits: the Data objects have a DataTable (iirc, I can be amiss on the names) that have a Calculate method which takes a string that contains simple operators to act on a datafield.
If you need performance, we need to do it slightly different though. I can help you with a regular expression to do the replace on your math expr.
And on yet another streak it is possible to create a simple parser yourself that does the Math.Pow and/or the other mathematical expressions for you. I believe there are already such expression validators available in .NET. Enough to warrant a new question? ;-)
If you need performance, we need to do it slightly different though. I can help you with a regular expression to do the replace on your math expr.
And on yet another streak it is possible to create a simple parser yourself that does the Math.Pow and/or the other mathematical expressions for you. I believe there are already such expression validators available in .NET. Enough to warrant a new question? ;-)
ASKER
I actually figured out a completely different workaround that is turning out to be ideal. A little bit of background, the functions are kinematic calculations that were originally devised using maple. I don't have a seat of maple right now, but I do have symbolic toolbox in MATLAB. Using the ccode() function I can take the matlab code and generate C code that is optimized (i.e. the function is broken down into subfunctions theoretically should run faster). I haven't proofed it yet, but it seems to do the trick.
That sounds like a much more viable option to me! Now you only need to learn to "talk" to a C/C++ file, if you need to access this from VB/C#.
ASKER
the ccode() command in matlab produces a text file that is compatible w/ C. All I need to do is copy it into my C# project and run a find replace for things like pow( to Math.Pow( and it's done. thanks for all your help, you've taught me a ton.
http://msdn.microsoft.com/en-us/library/6a71f45d.aspx