8

Having used the exponent operator ^ in the initialisation of a VB class's public constant following this question.

Public Const MaxValue As Double = MaxMantissa * (2 ^ MaxExponent)

I am converting the class to C#. however I find that C# does not have the same operator (^ is still an operator but only as bitwise xor).

Math.Pow() is given as an alternative to the operator, but cannot be used in a constant expression. How then can one initialise a constant with an exponent expression in C#?

(I do not use a value instead of an expression because the values within the expression, also constant, come from different places. MaxExponent comes from the base class, MaxMantissa is different in each derived class. Furthermore there are multiple constants like this in each derived class such as MaxPositiveValue, MinPositiveValue, MinNegativeValue, MaxNegativeValue, etc.)

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
Toby
  • 9,696
  • 16
  • 68
  • 132
  • 2
    C# doesn't have a power operator. – Tvde1 May 31 '17 at 08:58
  • @Tvde1 Yes, I've said that in the question. I'm asking if there is an alternative method for constant expressions. – Toby May 31 '17 at 08:58
  • 5
    `<<` works in limited cases, other than that you're just out of luck – harold May 31 '17 at 08:59
  • @harold good idea, but only works for whole numbers (cant do bit-wise operations on doubles AFAIK) – Toby May 31 '17 at 09:01
  • 4
    Is `readonly` an option? `public static readonly double MaxValue = MaxMantissa * Math.Pow(2.0, MaxExponent);` – Dmitry Bychenko May 31 '17 at 09:11
  • @DmitryBychenko It turns out that it is. Why I didn't think of that I don't know! Thank you - if you'd like to make that an answer I'll accept it – Toby May 31 '17 at 09:17

2 Answers2

8

Since in your particular case you want to raise 2 into MaxExponent power

2 ** MaxExponent

you can put it as a left shift, but if and only if MaxExponent is a small positive integer value:

1 << MaxExponent

Like this

// double: see comments below `1L` stands for `long` and so MaxExponent = [0..63]   
public const double MaxValue = MaxMantissa * (1L << MaxExponent);

In general case (when MaxExponent is an arbitrary double value), you can try changing const to readonly

public static readonly double MaxValue = MaxMantissa * Math.Pow(2.0, MaxExponent);
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • "if and only if `MaxExponent` is a small positive integer value" and what does this mean? This is too vague. Is 100 small? 101? And for what reason for it need to be a small positive integer value? – NotAPro Mar 28 '22 at 14:46
  • @NotAPro: if `2` is of type `int` (`Int32`) *small* `MaxExponent` means in "in `0 .. 31` range", if `2` is of type `long` (`Int64`; in this case we should use `L` suffix: `2L`) *small* `MaxExponent` is in `0..63` range – Dmitry Bychenko Mar 28 '22 at 15:14
3

You can't, basically (except, as noted, for the trivial case of powers of 2, which can be obtained via the shift operator).

You can hard-code the value and add a comment, or you can use a static readonly, but note that static readonly doesn't have the same "bake into the call-site" semantics. In most cases that doesn't present a problem.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900