Generic math functions

I want to create some functions that operate only on the numeric types but I don't particularly care what those types are. I'd rather rely on the invoker or .NET's automatic casting rules to create the answer in the appropriate type. I could declare two versions of every funciton one taking and returning doubles and the other decimals but that seems excessive and slow. Is there a way to make a function generic yet restrict its parameters to numeric types

 

As an example say you had the formula x*x + 2*y + z where x,y, and z are numbers of any of the standard .NET numeric types (and not necessarily the same type). How would you declare the function to manage this



Answer this question

Generic math functions

  • DeTraut

    That is simply not true. If you are using VS 2005 then you can use generics and generic constraints. It works similar to this:

    (This code was pulled from the C# 2.0 spec)

    public class EntityTable<K,E>
    where K: IComparable<K>, IPersistable
    where E: Entity, new()
    {
    public void Add(K key, E entity)
    {
    ...

    if (key.CompareTo(x) < 0) {...}
    ...
    }
    }


    It creates a class and then constrains the generic types to be certain types. You could create something like this and constrain your types to be only specific numeric types. Then create your operations on them accordingly.


  • DaaDa Ng

    Well Peter, you were correct in the aspect that this is not as easy to do as would originally be deduced. Check out this post from Eric Gunnerson's blog. It basically outlines a way in which you can do generic calculations. It is not the easiest and most straight forward way of doing it (or fastest for that matter), but it works. Hopefully by the time that C# 3.0 comes out they will add in support for primitive constraints.

    I definately overlooked the fact that generic constraints were not allowed, and from what I have been reading, there really isn't any good reason why they couldn't have been put in. Well, no reason other than the fact that it would have taken huge amounts of time. But I believe that forcing people to jump through hoops (and virtual table lookups) to do something as simple as being able to use generics for a calculation is absurd.



  • Richard Curley

    Justin - I’ve tried this and failed – maybe I’m too dense. If it’s possible as you say, would you be so kind as to write the generic function requested by OP For simplicity, assume the function will be called with T as a double.



  • venil

    This codeproject article is written in response to a.o. Eric Gunnerson's blog. It uses a second type parameter to specify the calculator type (e.g. IntCalculator) and valuetype specialization to eliminate the virtual call overhead and allow inlining. In other words, better hoops; it should be as fast as doing regular calculations, but is a little bit more complex to use.


  • Vinh Dang

    I think the best we could hope for is for C# 4.0 (version 3.0 will run on .NET 2.0, involving no framework updates) to have all numeric types implement a common interface like this:


    public interface Numeric<T> : IEquatable<T>, IComparable<T>
       where T : Numeric<T> {  
       T Add(T number);
      
       // ...
    }
    struct Int32 : Numeric<Int32> {
       Int32 Numeric<Int32>.Add(Int32 number) {
          return this + number;
       }
      
       // ...
    }

     

    This would still require some tricks in the Math class (either runtime typechecks or worse, moving its methods to Numeric<T>). But at least it would allow us to easily write classes like "Complex<T>", unlike the commonly stated solution to include static constraints like "where T : +(T,T)".



  • Ilya Haykinson

    Yep, it’s a killer all right.



  • chip_cary

    Chip – Thanks for the reference; an interesting read.

    Of course the next step in the problem is the need for Cosine<T>( T x ) and the like, so one winds up rewriting System.Math



  • marcusaurelius

    There is no way to do what you want to do in C#.



  • Generic math functions