I would like to create an extension that for a number, that given a
total would transform the number to percentage:
public static ???Number InPercentage(this ????Number value, ????
TotalValue) {
return value/Total*100;
}
Is this possible. I can see a problem: if the number is an integer the
returned value must be an integer to.
But I suppose that when applied to integers I could return also an
int.
Anyway, is an extension for this ok?
An extension method is okay for that sort of thing.
If I understand your other problem, you want to write a generic method
that would work for all numeric types (float, double, int, long etc).
Unfortunately, there's no good way to do this - you cannot use
arithmetic operators on values of generic type parameters, and there's
no way to constrain the latter to say "I want type T such that it has
operators * and /". There's an elusive IArithmetic<T> interface, which
should allow that sort of thing, and which seems to be sorta-promised
("maybe we will do that") for every .NET release starting with 2.0,
but it's not there yet, and so far it looks like it won't be in 4.0
either (at least I haven't seen it in any published changelogs).
For now, there are two ways you can go about it:
1) Just overload your extension method for all built-in numeric types
- or at least for all types that you expect it to be used (e.g.
probably not worth doing it for sbyte/byte/short/ushort). See
Enumerable.Sum() for an example of that approach.
2) Convert the value that is passed to you to some type with "good
enough" range and precision (which is really either Double or Decimal,
but it's hard to say which is better), perform arithmetic on that, and
then use Convert.ChangeType to convert it back to the expected type:
public static TNumeric InPercentage<TNumeric>(this TNumeric value,
TNumeric total) {
return Convert.ChangeType(Convert.ToDouble(value) /
Convert.ToDouble(total) * 100, typeof(T));
}
The disadvantage of #2 is that it is slower, and, for Decimal, it may
result in undesired rounding behavior. The disadvantage of #1 is that
it's a lot of repetitive code. Neither gives you a fully generic
solution (e.g.. when BigInteger comes in .NET 4.0, neither will be
able to handle it properly, though #2 will do slightly better than #1;
and neither will be able to handle custom Complex<T> type with
overloaded operators * and / at all).