How to use scientific notation in const fields? - c#

I'm working in a math library, and due to the inherent troubles of working with double I am coding all equality comparisons type a == b as Math.Abs(a - b) <= epsilon.
Also, by default, I want my formatted strings to be generated with the maximum considered precision. That is, if epsilon is 0.001 I want my default format to be N3.
Happily I did the following:
public static class Math3D
{
internal const int ROUND = 3;
public const double Epsilon = 1e-ROUND;
}
...and I got a compilation error. Apparently this is not allowed.
With this limitation I see no way I can define both interdependant constants as consts. Obviously I can define Epsilon as a readonly field but I feel doing so is somehow conceptually wrong. Am I missing an obvious way of how to do this?

If you're going to possibly be changing it, you should use readonly here. const should really be used for things that will never change, like π. The reason for this is because of a subtle difference between const and readonly.
The main issue is that if you change the value of the const, you must recompile all dependent clients that use the const, otherwise you can shoot yourself in the foot, badly. So for values that might change, don't use const, use readonly.
So, if the value is never going to change, just use const and then don't worry about defining Epsilon in terms of ROUND, just say:
internal const int ROUND = 3;
public const double Epsilon = 1e-3;
If you really want to make sure you don't accidentally change one without changing the other, you could add a small check in the constructor:
if (Epsilon != Math.Pow(10, -ROUND)) {
throw new YouForgotToChangeBothConstVariablesException();
}
You could even add conditional compilation so that only gets compiled in debug releases.
If it is going to change, use static readonly:
internal readonly int ROUND = 3;
public static readonly double Epsilon = Math.Pow(10, -ROUND);
With this limitation I see no way I can define both interdependant constants as consts. [...] Am I missing an obvious way of how to do this?
No, you need to do some kind of math using Math.Pow or Math.Log to go between ROUND and Epsilon and those are not acceptable for compile-time usage with const. You could write a miniature code generator to spit out these two lines of code based on a single input value, but I really question the value of investing time into that.

1e-ROUND, specifically 1e is not a valid literal integer. You would have to do something like,
public static readonly double Epsilon =
decimal.Parse(
string.Format("1E-{0}", ROUND),
System.Globalization.NumberStyles.Float);
Also, note the static readonly since you cannot use a const when the expression won't be known until runtime. The static readonly will work similarly to a const in this scenario.
If you prefer not dealing with strings, you can always do,
public static readonly double Epsilon = Math.Pow(10, -ROUND);

You could always just hard code the 3. Seeing as you are using constants, then have no intention of ever changing the value to anything other than 3 right? So you don't need to worry too much about DRY.
public static class Math3D
{
internal const int ROUND = 3;
public const double Epsilon = 1e-3;
}
If you are thinking you might want to change the 3, then const is not for you and your question becomes moot.

Edit:
This is not a direct answer to your question but have you considered changing Round and Epsilon into writable fields? If you use these for formatting / rounding, it's almost guaranteed they'll need to change on occasion - neither a const nor a readonly field will work for that.
public static class Math3D
{
internal static int s_Round;
internal static double s_Epsilon;
static Math3D ()
{
Round = 3;
}
public static double Epsilon
{
get
{
return ( s_Epsilon );
}
}
public static int Round
{
get
{
return ( s_Round );
}
set
{
// TODO validate
s_Round = value;
s_Epsilon = Math.Pow ( 10, -s_Round );
}
}
}
It's a clearly readable solution that won't break when you change things in the future.

Related

Pattern for Creating a Simple and Efficient Value type

Motivation:
In reading Mark Seemann’s blog on Code Smell: Automatic Property he says near the end:
The bottom line is that automatic properties are rarely appropriate.
In fact, they are only appropriate when the type of the property is a
value type and all conceivable values are allowed.
He gives int Temperature as an example of a bad smell and suggests the best fix is unit specific value type like Celsius. So I decided to try writing a custom Celsius value type that encapsulates all the bounds checking and type conversion logic as an exercise in being more SOLID.
Basic requirements:
Impossible to have an invalid value
Encapsulates conversion operations
Effient coping (equivalent to the int its replacing)
As intuitive to use as possible (trying for the semantics of an int)
Implementation:
[System.Diagnostics.DebuggerDisplay("{m_value}")]
public struct Celsius // : IComparable, IFormattable, etc...
{
private int m_value;
public static readonly Celsius MinValue = new Celsius() { m_value = -273 }; // absolute zero
public static readonly Celsius MaxValue = new Celsius() { m_value = int.MaxValue };
private Celsius(int temp)
{
if (temp < Celsius.MinValue)
throw new ArgumentOutOfRangeException("temp", "Value cannot be less then Celsius.MinValue (absolute zero)");
if (temp > Celsius.MaxValue)
throw new ArgumentOutOfRangeException("temp", "Value cannot be more then Celsius.MaxValue");
m_value = temp;
}
public static implicit operator Celsius(int temp)
{
return new Celsius(temp);
}
public static implicit operator int(Celsius c)
{
return c.m_value;
}
// operators for other numeric types...
public override string ToString()
{
return m_value.ToString();
}
// override Equals, HashCode, etc...
}
Tests:
[TestClass]
public class TestCelsius
{
[TestMethod]
public void QuickTest()
{
Celsius c = 41;
Celsius c2 = c;
int temp = c2;
Assert.AreEqual(41, temp);
Assert.AreEqual("41", c.ToString());
}
[TestMethod]
public void OutOfRangeTest()
{
try
{
Celsius c = -300;
Assert.Fail("Should not be able to assign -300");
}
catch (ArgumentOutOfRangeException)
{
// pass
}
catch (Exception)
{
Assert.Fail("Threw wrong exception");
}
}
}
Questions:
Is there a way to make MinValue/MaxValue const instead of readonly? Looking at the BCL I like how the meta data definition of int clearly states MaxValue and MinValue as compile time constants. How can I mimic that? I don’t see a way to create a Celsius object without either calling the constructor or exposing the implementation detail that Celsius stores an int.
Am I missing any usability features?
Is there a better pattern for creating a custom single field value type?
Is there a way to make MinValue/MaxValue const instead of readonly?
No. However, the BCL doesn't do this, either. For example, DateTime.MinValue is static readonly. Your current approach, for MinValue and MaxValue is appropriate.
As for your other two questions - usability and the pattern itself.
Personally, I would avoid the automatic conversions (implicit conversion operators) for a "temperature" type like this. A temperature is not an integer value (in fact, if you were going to do this, I would argue that it should be floating point - 93.2 degrees C is perfectly valid.) Treating a temperature as an integer, and especially treating any integer value implicitly as a temperature seems inappropriate and a potential cause of bugs.
I find that structs with implicit conversion often cause more usability problems than they address. Forcing a user to write:
Celsius c = new Celcius(41);
Is not really much more difficult than implicitly converting from an integer. It is far more clear, however.
I think from a usability point of view I would opt for a type Temperature rather than Celsius. Celsius is just a unit of measure while a Temperature would represent an actual measurement. Then your type could support multiple units like Celsius, Fahrenheit and Kelvin. I would also opt for decimal as backing storage.
Something along these lines:
public struct Temperature
{
private decimal m_value;
private const decimal CelsiusToKelvinOffset = 273.15m;
public static readonly Temperature MinValue = Temperature.FromKelvin(0);
public static readonly Temperature MaxValue = Temperature.FromKelvin(Decimal.MaxValue);
public decimal Celsius
{
get { return m_value - CelsiusToKelvinOffset; }
}
public decimal Kelvin
{
get { return m_value; }
}
private Temperature(decimal temp)
{
if (temp < Temperature.MinValue.Kelvin)
throw new ArgumentOutOfRangeException("temp", "Value {0} is less than Temperature.MinValue ({1})", temp, Temperature.MinValue);
if (temp > Temperature.MaxValue.Kelvin)
throw new ArgumentOutOfRangeException("temp", "Value {0} is greater than Temperature.MaxValue ({1})", temp, Temperature.MaxValue);
m_value = temp;
}
public static Temperature FromKelvin(decimal temp)
{
return new Temperature(temp);
}
public static Temperature FromCelsius(decimal temp)
{
return new Temperature(temp + CelsiusToKelvinOffset);
}
....
}
I would avoid the implicit conversion as Reed states it makes things less obvious. However I would overload operators (<, >, ==, +, -, *, /) as in this case it would make sense to perform these kind of operations. And who knows, in some future version of .net we might even be able to specify operator constraints and finally be able to write more reusable data structures (imagine a statistics class which can calculate statistics for any type which supports +, -, *, /).
DebuggerDisplay is useful touch. I'd add unit of measurements "{m_value} C" so you can immediately see the type.
Depending on target usage you may also want to have generic conversion framework to/from base units in addtion to concrete classes. I.e. store values in SI units, but be able to display/edit based on culture like (degrees C, km, kg) vs. (degrees F, mi, lb).
You may also check out F# measurement units for additioanl ideas ( http://msdn.microsoft.com/en-us/library/dd233243.aspx ) - note that it is compile time construct.
I think this is a perfectly fine implementation pattern for value types. I've done similar things in the past that have worked out well.
Just one thing, since Celsius is implicitly convertible to/from int anyway, you can define the bounds like this:
public const int MinValue = -273;
public const int MaxValue = int.MaxValue;
However, in reality there's no practical difference between static readonly and const.

Other equivalent to enum?

I like to use enum as value holders whereever possible and I like it. It is easy to use i.e. just put a dot and see values. It is a good replacement of hard code some time.
But still it has some limitations. We cannot put special characters in values and some other.
Actually I am trying to make code reusable. Please guide me. Is there some technique or way that I can use some data structure like enum that is flexible but have no limitations.
You could use constants; they are immutable and can have any value.
See also: http://msdn.microsoft.com/en-us/library/ms173119.aspx
If I cannot use an enum for a set of predefined values, I use a class of static constants. They look much the same in use, but the values can be anything from a decimal to a string to a struct or class. I've done this for predefined cell color schemes in GridViews, much like the built-in Color class has predefined constant values. Mathematical and scientific constants such as e and Pi (if you wanted different values than are provided by the Math class), or the acceleration of gravity (9.8m/s2), or the speed of light (299,792,458m/s), can also be specified in this way.
If you think you can't use Enums because you need to store predefined string values, try this handy trick using the System.ComponentModel Description attribute:
public Enum MyStrings
{
[Description("This is string one")] StringOne,
[Description("This is a different string")] StringTwo,
...
}
To get the strings out, you simply examine the Description attribute, the code for which is a little messy but can be easily hidden behind an extension method:
public static string GetDescription(this Enum enumValue)
{
object[] attr = enumValue.GetType().GetField(enumValue.ToString())
.GetCustomAttributes(typeof (DescriptionAttribute), false);
return (attr.Length > 0)
? ((DescriptionAttribute) attr[0]).Description
: String.Empty;
}
Usage:
var stringOne = MyStrings.StringOne.GetDescription(); //"This is string one"
In this case, you can also consider using a Resource file. The value of the string can be changed from outside the scope of the program, without a recompile.
Not sure what exactly you need (re: "special characters"), but you could simply use some constants and put them into a static class, e.g:
public static class MyConstants
{
/// <summary>documentation here</summary>
public const string ValueA = "somevalue";
/// <summary>documentation here</summary>
public const string ValueB = "something else with special characters &#";
// etc.
}
Usage:
var x = MyConstants.ValueB;
One issue you might find with enums and more especially constants is that if you change the source assembly which defines the enum or constant, but don't recompile dependent assemblies, you'll end up mismatching in the source and dependent assemblies. For example:
public const int myConst = 5;
You later change this to:
public const int myConst = 10;
In the source assembly, which was rebuilt, it's 10. But it's 5 in any dependent assemblies that were not rebuilt.
To avoid this, use readonly instead of const. For example:
public readonly int myConst = 5;
This is different than a const, which is more like a C++ #define which causes the value to be placed directly in code. Readonly will cause a lookup at runtime, so if you don't recompile your dependent assemblies you'll still get the correct, updated value.

Enum vs Constants/Class with Static Members?

I have a set of codes that are particular to the application (one to one mapping of the code to its name), and I've been using enums in C# to represent them. I'm not sure now if that is even necessary. The values never change, and they are always going to be associated with those labels:
Workflow_Status_Complete = 1
Workflow_Status_Stalled = 2
Workflow_Status_Progress = 3
Workflow_Status_Complete = 4
Workflow_Status_Fail = 5
Should I use an enum or a class with static members?
Static members of type int seems to be inferior to an enum to me. You lose the typesafety of an enum. And when debugging you don't see the symbolic name but just a number.
On the other hand if an entry consists of more than just a name/integervalue pair a class can be a good idea. But then the fields should be of that class and not int. Something like:
class MyFakeEnum
{
public static readonly MyFakeEnum Value1=new MyFakeEnum(...);
}
Use an enum. Even though your codes never change, it will be difficult to know what the value represents just by inspection. One of the many strengths of using enums.
enum RealEnum : uint
{
SomeValue = 0xDEADBEEF,
}
static class FakeEnum
{
public const uint SomeValue = 0xDEADBEEF;
}
var x = RealEnum.SomeValue;
var y = FakeEnum.SomeValue;
// what's the value?
var xstr = x.ToString(); // SomeValue
var ystr = y.ToString(); // 3735928559
Not even the debugger will help you much here, especially if there are many different values.
Check out the State Pattern as this is a better design. With the idea you are using you'll end up with a large switch/if-else statement which can be very difficult to keep up.
I would lean towards enums as they provide more information and they make your codes "easier to use correctly and difficult to use incorrectly". (I think the quote is from The Pragmatic Programmer.

order initializiation static parameter

Is there any specification for the order in which static readonly parameters are initialized?
In the following example, can one be sure, the array is always created with a length of 6?
public class Foo {
private static readonly int MAX_STACKSIZE = 6;
private static readonly int[] m_stack = new int[MAX_STACKSIZE];
}
Or is there any chance of m_stack being initialized before MAX_STACKSIZE ?
#Edit: changed const to static readonly
EDIT: This answer was written when the sample code contained "const" instead of "static readonly". It's not valid for the current version of the question - I may write another answer to deal with that at some point, but I don't have time right now.
That won't be valid C# anyway, as you can't set a const int[] to anything other than null.
However, in the more general case, section 10.4 of the C# spec applies:
Constants are permitted to depend on other constants within the same program as long as the dependencies are not of a circular nature. The compiler automatically arranges to evaluate the constant declarations in the appropriate order.
It then gives the following example:
class A
{
public const int X = B.Z + 1;
public const int Y = 10;
}
class B
{
public const int Z = A.Y + 1;
}
and says...
the compiler first evaluates A.Y, then evaluates B.Z, and finally evaluates A.X, producing the values 10, 11 and 12 in that order.

Creating a percentage type in C#

My application deals with percentages a lot. These are generally stored in the database in their written form rather than decimal form (50% would be stored as 50 rather than 0.5). There is also the requirement that percentages are formatted consistently throughout the application.
To this end i have been considering creating a struct called percentage that encapsulates this behaviour. I guess its signature would look something like this:
public struct Percentage
{
public static Percentage FromWrittenValue();
public static Percentage FromDecimalValue();
public decimal WrittenValue { get; set; }
public decimal DecimalValue { get; set; }
}
Is this a reasonable thing to do? It would certianly encapsulate some logic that is repeated many times but it is straightforward logic that peopel are likely to understand. I guess i need to make this type behave like a normal number as much as possible however i am wary of creating implicit conversions to a from decimal in case these confuse people further.
Any suggestions of how to implement this class? or compelling reasons not to.
I am actually a little bit flabbergasted at the cavalier attitude toward data quality here.
Unfortunately, the colloquial term "percentage" can mean one of two different things: a probability and a variance. The OP doesn't specify which, but since variance is usually calculated, I'm guessing he may mean percentage as a probability or fraction (such as a discount).
The extremely good reason for writing a Percentage class for this purpose has nothing to do with presentation, but with making sure that you prevent those silly silly users from doing things like entering invalid values like -5 and 250.
I'm thinking really more about a Probability class: a numeric type whose valid range is strictly [0,1]. You can encapsulate that rule in ONE place, rather than writing code like this in 37 places:
public double VeryImportantLibraryMethodNumber37(double consumerProvidedGarbage)
{
if (consumerProvidedGarbage < 0 || consumerProvidedGarbage > 1)
throw new ArgumentOutOfRangeException("Here we go again.");
return someOtherNumber * consumerProvidedGarbage;
}
instead you have this nice implementation. No, it's not fantastically obvious improvement, but remember, you're doing that value-checking in each time you're using this value.
public double VeryImportantLibraryMethodNumber37(Percentage guaranteedCleanData)
{
return someOtherNumber * guaranteedCleanData.Value;
}
Percentage class should not be concerned with formatting itself for the UI. Rather, implement IFormatProvider and ICustomFormatter to handle formatting logic.
As for conversion, I'd go with standard TypeConverter route, which would allow .NET to handle this class correctly, plus a separate PercentageParser utility class, which would delegate calls to TypeDescriptor to be more usable in external code. In addition, you can provide implicit or explicit conversion operator, if this is required.
And when it comes to Percentage, I don't see any compelling reason to wrap simple decimal into a separate struct other than for semantic expressiveness.
It seems like a reasonable thing to do, but I'd reconsider your interface to make it more like other CLR primitive types, e.g. something like.
// all error checking omitted here; you would want range checks etc.
public struct Percentage
{
public Percentage(decimal value) : this()
{
this.Value = value
}
public decimal Value { get; private set; }
public static explicit operator Percentage(decimal d)
{
return new Percentage(d);
}
public static implicit operator decimal(Percentage p)
{
return this.Value;
}
public static Percentage Parse(string value)
{
return new Percentage(decimal.Parse(value));
}
public override string ToString()
{
return string.Format("{0}%", this.Value);
}
}
You'd definitely also want to implement IComparable<T> and IEquatable<T> as well as all the corresponding operators and overrides of Equals, GetHashCode, etc. You'd also probably also want to consider implementing the IConvertible and IFormattable interfaces.
This is a lot of work. The struct is likely to be somewhere in the region of 1000 lines and take a couple of days to do (I know this because it's a similar task to a Money struct I wrote a few months back). If this is of cost-benefit to you, then go for it.
This question reminds me of the Money class Patterns of Enterprise Application Architecture talks about- the link might give you food for thought.
Even in 2022, .Net 6 I found myself using something just like this. I concur with Michael on his answer for the OP and like to extend it for future Googlers.
Creating a value type would be indispensable in explaining the domain's intent with enforced immutability. Notice especially in the Fraction Record you will get a Quotient that would normally cause an exception however here we can safely show d / 0 with no error, likewise all other inherited children are also granted that protection (It also offers an excellent place to establish simple routines to check validity, data rehydration (as if DBA's don't make mistakes), serialization concerns just to name a few.)
namespace StackOverflowing;
// Honor the simple fraction
public record class Fraction(decimal Dividend, decimal Divisor)
{
public decimal Quotient => (Divisor > 0.0M) ? Dividend / Divisor : 0.0M;
// Display dividend / divisor as the string, not the quotient
public override string ToString()
{
return $"{Dividend} / {Divisor}";
}
};
// Honor the decimal based interpretation of the simple fraction
public record class DecimalFraction(decimal Dividend, decimal Divisor) : Fraction(Dividend, Divisor)
{
// Change the display of this type to the decimal form
public override string ToString()
{
return Quotient.ToString();
}
};
// Honor the decimal fraction as the basis value but offer a converted value as a percentage
public record class Percent(decimal Value) : DecimalFraction(Value, 100.00M)
{
// Display the quotient as it represents the simple fraction in a base 10 format aka radix 10
public override string ToString()
{
return Quotient.ToString("p");
}
};
// Example of a domain value object consumed by an entity or aggregate in finance
public record class PercentagePoint(Percent Left, Percent Right)
{
public Percent Points => new(Left.Value - Right.Value);
public override string ToString()
{
return $"{Points.Dividend} points";
}
}
[TestMethod]
public void PercentScratchPad()
{
var approximatedPiFraction = new Fraction(22, 7);
var approximatedPiDecimal = new DecimalFraction(22, 7);
var percent2 = new Percent(2);
var percent212 = new Percent(212);
var points = new PercentagePoint(new Percent(50), new Percent(40));
TestContext.WriteLine($"Approximated Pi Fraction: {approximatedPiFraction}");
TestContext.WriteLine($"Approximated Pi Decimal: {approximatedPiDecimal}");
TestContext.WriteLine($"2 Percent: {percent2}");
TestContext.WriteLine($"212 Percent: {percent212}");
TestContext.WriteLine($"Percentage Points: {points}");
TestContext.WriteLine($"Percentage Points as percentage: {points.Points}");
}
 PercentScratchPad
Standard Output: 
TestContext Messages:
Approximated Pi Fraction: 22 / 7
Approximated Pi Decimal: 3.1428571428571428571428571429
2 Percent: 2.00%
212 Percent: 212.00%
Percentage Points: 10 points
Percentage Points as percentage: 10.00%
I strongly recommend you just stick with using the double type here (I don't see any use for the decimal type either, as wouldn't actually seem to require base-10 precision in the low decimal places). By creating a Percentage type here, you're really performing unnecessary encapsulation and just making it harder to work with the values in code. If you use a double, which is customary for storying percentages (among many other tasks), you'll find dealing with the BCL and other code a lot nicer in most cases.
The only extra functionality that I can see you need for percentages is the ability to convert to/from a percentage string easily. This can be done very simply anyway using single lines of code, or even extension methods if you want to abstract it slightly.
Converting to percentage string :
public static string ToPercentageString(this double value)
{
return value.ToString("#0.0%"); // e.g. 76.2%
}
Converting from percentage string :
public static double FromPercentageString(this string value)
{
return double.Parse(value.SubString(0, value.Length - 1)) / 100;
}
I think you may be mixing up presentation and logic here. I would convert the percentage to a decimal or float fraction (0.5) when getting it from the database and then let the presentation deal with the formatting.
I'd not create a separate class for that - this just creates more overhead. I thinkg it will be faster just to use double variables set to the database value.
If it is common knowledge that the database stores percentages as 50 instead of 0.5, everybody will understand statemens like part = (percentage / 100.0) * (double)value.

Categories

Resources