Number Extension

S

shapper

Hello,

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?

How can I do this?

Thanks,
Miguel
 
A

Arne Vajhøj

shapper said:
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?

The real problem is to find a base type that allows
/ and *.

I would go for the simple:

public static class MyExtensions
{
public static int Percent(this int x, int total)
{
return 100 * x / total;
}
public static double Percent(this double x, double total)
{
return 100 * x / total;
}
}

Arne
 
P

Pavel Minaev

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).
 
S

shapper

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).

Thank You!!

I am just finding extensions and this is becoming really useful.

I think in this situation the decrease of speed in 2 will not be very
harmful.
I am display in an MVC View Page and the Model passed includes 3 Count
values.
So I will do it only three times: Model.CountA.Percentage
(Model.CountTotal)

Thanks Once Again (To Both),
Miguel
 
P

Pavel Minaev

I am just finding extensions and this is becoming really useful.

Just be careful not to overdo it. Extension methods are good ways to
extend existing types in an unintrusive way (interfaces especially),
but they are somewhat confusing when reading code; and, of course, the
possibility of name clash is much higher. In general, something has to
be used very often to make turning it into an extension method viable.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top