# Potential additions to the Math class [Katy King]

### Potential additions to the Math class [Katy King]

In preparation for the next version of the product, we've collected suggestions for additions to the Math class and related classes.  To give you an idea of the kinds of things people ask us for, here are a list of some of the requests we've received.  We’re curious to know which of  these (if any) seem interesting to this audience, and why?  (Namely, what are you working on that you could leverage the specific capability listed?)  Is there anything missing from the list which would be useful?

• Implement single-precision trig (and other) overloads.  For many functions that currently take a Double, add overloads that take a Single.
• Inverse hyperbolic functions (ACosh, ASinh, and ATanh)
• More trig functions (csc, sec, cot)
• Min and Max overloads that take more than two arguments
• Other functions that take a variable number of args - Sum() and Average(), for example
• Complex number support
• Bitshifting - RightShift and LeftShift on integral types (not currently available in VB)
• Arbitrary-precision decimal numbers (BigDecimal)
• Factorial
• Permutations, Combinations (see <http://mathforum.org/dr.math/faq/faq.comb.perm.html> for definitions)
• Convert between degrees and radians
• Support for vectors and vector math (probably not in the Math class)
• Add new values to the MidpointRounding enum - which ones?
• Provide a different math model for operations, that throws instead of obeying IEEE (returning NaN/Infinity).  (Note that it is extremely unlikely that we will change our model at this point.)
• Here's my opinion. + is good, - is not so good.

- Single-precision trig (and other) overloads. Not very useful. I believe most calculations should be done (but not necessarily stored) in Double precision anyway.

++ Inverse hyperbolic functions. Yes, please. This is clearly missing.

-- More trig functions (csc, sec, cot). Not very useful: they have a very simple expression in terms of sin,cos, etc. Most expressions are easier to read with sin, cos than with csc, sec anyway.

++ Min and Max overloads that take more than two arguments. Definite yes. System.Math is the only place to put these.

+ Sum() and Average(), for example. Useful but not a priority.

+ Complex number support. Sounds good, but it's hard to do this right.

o Arbitrary-precision decimal numbers (BigDecimal): this is already available through the J# library (vjslib.dll)

o+ Factorial, Permutations, Combinations: useful.

++ Math.Pow() overload for Decimal: Yes, and what about Math.Pow for integer powers?

- Convert between degrees and radians: define the conversion factor as a constant?

+ Support for vectors and vector math (probably not in the Math class). Many .NET assumptions don't hold for vectors, with severe performance penalties if you ignore this.

+ Add new values to the MidpointRounding enum - which ones? Simply provide the 4 'standard' rouding modes wherever available: up, down, to zero, to nearest/even.

++ Provide a different math model for operations, that throws instead of obeying IEEE (returning NaN/Infinity). This is IEEE *default* behavior. Could be extremely useful, along with "sticky bits", but exceptions would have to be made a lot cheaper for this to live up to its potential.

Other items I would like to see:

+++++ Have the JIT inline value type methods.

+++ Support for floating-point exception flags ("sticky bits")

++ More meaningful constants for Single and Double: NegativeZero and constants related to range and precision, including the 'actual' Epsilon. (See float.h for inspiration.)

+ Three more functions: Expm1 (Exp(x)-1 for higher precision when x is around 0), Log1p (Log(1+x) for x around 0) and hypot(x, y).

+ Support for setting rounding modes.
• You must know, the number one "gotcha" about Math on the newsgroups is Round? No one expects that function to do bankers rounding, and mathematically it is usually useless.

I like these new items but I do not think Vector or Matrix should go into the System dll.
• So much cool feedback here all, we really appreciate it, thanks. On Rounding by the way, check out the new overloads in recent bits, and you'll notice we have a new overload which allows you tou round the traditional way ;-)
• Shital, your criticism miss two crucial points. Java's numerical support is worse than .NET's. Also, the BCL is an excellent *general purpose* library. Like it or not, numerical computing is not mainstream.

The issue I have is with the platform itself, which should be broad enough to support specialized applications. Some design decisions in .NET are extremely questionable from a numerical performance perspective. These should be addressed first. My list of top issues:

- inlining of value type methods. It seems they didn't address the #1 performance scenario for value types.

- the CLR throws arithmetic exceptions, which are way too expensive to be useful in numerical computations.

- compliance with the IEEE-754/IEC 60559 standard is minimal. No rounding modes, no exception flags, no traps.

- reference types with value semantics are assumed to be immutable. This is manageable for strings (thanks to StringBuilder) but doesn't work at all for vectors and matrices.

- example: C# does not support overloading of compound assignment operators. x+=y is always interpreted as x = x+y. This leaves 2 choices: take a huge performance hit (up to 50x), or don't use operator overloading (even though math objects are primary candidates for overloading).

None of these are BCL issues, so a comment on the BCL team blog may not be the best place to list them. Then again, it shows what must happen before some functionality can be included in the BCL.
• Matrix math and rounding options would be a great thing...
• We really need to have interfaces that define permissable mathematical operations that types can support. This will allow us to build very cool generic algorithms, along with the very cool generic containers.

See: http://www.lambda-computing.com/publications/articles/generics/
• Tips
• I really *would* like to see single-precision versions of the math functions, but I can see two potential problems with that:

Aren't all the calculations done at the same precision anyway? Unless there's a special operator for single-precision floating point sine, putting overloads on there might give the illusion that you'll get better performance. I'd love to be wrong here, but isn't single-precision only helpful for saving space?

Also, this would potentially break source-code compatability. Wouldn't the following code change?

BinaryWriter writer = ...;
float number = ...;
writer.Write(Math.Sin(number));

Currently, this would involve an implicit cast up to double, and a double would be written. With a single-precision overload, a float would be written.
• Oh.. Anyway, I'd vote for more trig and hyperbolic functions (for completeness...really...that's important to me in a library).

The Min and Max overloads could be handled in a nice generics algorithms library that worked for all IComparable<T>, so you can leave those out, if you must.

Sum and Average seems pretty silly...everybody should know how to do that (maybe put them in Micorosft.VisualBasic?)

BigInteger and BigDecimal would be great, but they would need to be complete and well-performing. Please consider this. I mean, Java has it.

BitShifting seems silly. Even VB has it now, and multiplcation works in most cases. Perhaps Bit Rotating, but that can also be implemented with Bit Shifting (but is the JIT smart enough to optimize a bit-rotate on x86?).

Permutations and Combinations should be part of a nice statistical library. I guess Sum, Average, StandardDeviation and the like should go there (yeah...I guess Sum and Average would be okay in a Stats library).

Math.Pow(decimal) should be in for completeness. Seems like an oversight, to me.

Radian/Degree conversion...I could take it or leave it. You have Math.PI, which is all I ever need. You don't really want to open the floodgates for all unit conversions, do you?

Vectors and Vector Math...no...I don't have faith that it would be done right...and if you do make them, then *DON'T* design them like System.Drawing.Point/PointF/Size/SizeF with tons of missing/screwed up operators and weird semmantics. I'm not too happy with DirectX's implementation of Vector, either, but it's a start. Besides, Vector really needs to be part of a larger math package...it's just the beginning. Maybe I'd accept it if you let me write it. :-)

More MidpointRounding values would be great. I'm surprised rounding-up isn't supported, as that's what most school kids are taught. I'd propose that and rounding down (for completeness--again important), as well as some accepted pseudo-random rounding for high statistical accuracy.

And a throwing math model would be nice, too. In C# I'd suggest a syntax such as "checked float { ... }" similar to "checked { ... }". That way a new keyword wouldn't be needed, and existing checked/unchecked code dealing with integers wouldn't break if they contained floating-point operations.
• "x+=y is always interpreted as x = x+y."
Uh, because that is the way it is supposed to work...
x+=y is just a shorter way of saying x=x+y. It would be stupid to change the behavior. Having the += operator not do addition would be confusing.
• Matt,

Of course the result of x += y should be that x equals x+y.

The difference is that x += y now always creates a new instance. You don't "add y to x", you "give x the result of x+y."

Aside from the slight semantic difference, this is also a performance trap. It's widely documented that += is not to be used for string concatenation inside loops. Ok, for strings we have StringBuilder, but that solution isn't feasible for all such "large value types" (i.e. reference types with value semantics). Two primary examples are vectors and matrices.

So I want in C# what C++/CLI does: allow me to optimize when I want to (i.e. override +=), and use the default behavior when I don't care to optimize.
• As somebody who writes lots of numerical PDE stuff in the financial derivatives industry, I can tell you a few things:

1. The guys selling numerical libraries DO NOT GET the concept of a well designed API. Most of them still come from the C world and there are very few .dlls out there that actually even have a native interface to .NET (ie no COM). Given that you didn't have support for this stuff in the beginning, anybody doing any sort of numerics work either wrote their own custom stuff or used somebody else's. The single best thing you could do is go out and beat up the third party vendors about their API designs. They're terrible. Maybe MS API certification or something? Realistically, you guys aren't ever (nor should you) going to be doing anything like implementing FFT or something. So if you really want to improve offerings for numerics, put the right kind of "positive pressure" on the 3rd parties.

2. As a result of #1, you have to be really careful about coming up with new monolithic objects at this point. Most library guys actually develop their own vector and matrix classes. Personally, I'd prefer that any vector and matrix support offered by the framework come in the form of either operator overloading of value-type arrays in the framework or through additional static methods. My personal linear algebra library setup is called from my namespace System.MathX.LinearAlgebra, and contains only static methods.

3. Complex numbers would be a very nice feature, but my understanding is that right now there's some kind of inlining problem with structs or something that makes them perform poorly... In any case, my industry doesn't really need complex numbers but most engineers use them all the time.

I tried to stick to things that I felt actually added something that others had not said.
• Tips
• 1) Min and Max overloads that take more than two arguments - important, also take array[]; general feature
Other functions that take a variable number of args - Sum() and Average(), and Product(), again on args[] and on normal arays
Math.Pow() overload for Decimal - yes, this is important
2) My tips - mybe not for Math - more support for converts to/from hexnumbers
Page 2 of 3 (36 items) 123