La mancanza di un operatore esponenziale per C # è stata una grande seccatura per noi quando cercavamo una nuova lingua per convertire il nostro software di calcolo dal buon vecchio vb6.
Sono contento che siamo andati con C # ma mi dà ancora fastidio ogni volta che scrivo un'equazione complessa che include esponenti. Il metodo Math.Pow () rende le equazioni abbastanza difficili da leggere IMO.
La nostra soluzione era quella di creare una classe DoubleX speciale in cui sovrascrivessimo l'operatore ^ (vedi sotto)
Funziona abbastanza bene fintanto che dichiari almeno una delle variabili come DoubleX:
DoubleX a = 2;
DoubleX b = 3;
Console.WriteLine($"a = {a}, b = {b}, a^b = {a ^ b}");
o usa un convertitore esplicito su doppio standard:
double c = 2;
double d = 3;
Console.WriteLine($"c = {c}, d = {d}, c^d = {c ^ (DoubleX)d}"); // Need explicit converter
Un problema con questo metodo è che l'esponente viene calcolato nell'ordine sbagliato rispetto ad altri operatori. Questo può essere evitato mettendo sempre un extra () attorno all'operazione che rende ancora più difficile leggere le equazioni:
DoubleX a = 2;
DoubleX b = 3;
Console.WriteLine($"a = {a}, b = {b}, 3+a^b = {3 + a ^ b}"); // Wrong result
Console.WriteLine($"a = {a}, b = {b}, 3+a^b = {3 + (a ^ b)}"); // Correct result
Spero che questo possa essere d'aiuto ad altri che usano molte equazioni complesse nel loro codice, e forse qualcuno ha anche un'idea di come migliorare questo metodo ?! :-)
Classe DoubleX:
using System;
namespace ExponentialOperator
{
/// <summary>
/// Double class that uses ^ as exponential operator
/// </summary>
public class DoubleX
{
#region ---------------- Fields ----------------
private readonly double _value;
#endregion ------------- Fields ----------------
#region -------------- Properties --------------
public double Value
{
get { return _value; }
}
#endregion ----------- Properties --------------
#region ------------- Constructors -------------
public DoubleX(double value)
{
_value = value;
}
public DoubleX(int value)
{
_value = Convert.ToDouble(value);
}
#endregion ---------- Constructors -------------
#region --------------- Methods ----------------
public override string ToString()
{
return _value.ToString();
}
#endregion ------------ Methods ----------------
#region -------------- Operators ---------------
// Change the ^ operator to be used for exponents.
public static DoubleX operator ^(DoubleX value, DoubleX exponent)
{
return Math.Pow(value, exponent);
}
public static DoubleX operator ^(DoubleX value, double exponent)
{
return Math.Pow(value, exponent);
}
public static DoubleX operator ^(double value, DoubleX exponent)
{
return Math.Pow(value, exponent);
}
public static DoubleX operator ^(DoubleX value, int exponent)
{
return Math.Pow(value, exponent);
}
#endregion ----------- Operators ---------------
#region -------------- Converters --------------
// Allow implicit convertion
public static implicit operator DoubleX(double value)
{
return new DoubleX(value);
}
public static implicit operator DoubleX(int value)
{
return new DoubleX(value);
}
public static implicit operator Double(DoubleX value)
{
return value._value;
}
#endregion ----------- Converters --------------
}
}
**
come operatore di esponenziazione infix.