Reputation: 7
I've been both scratching and banging my head on this one. I suspect I;m just being daft here, but I can't seem to get a const, or static, member to initialize so I can use it throughout a class.
Here's an example that demonstrates my problem (or rather my misunderstanding):
using System;
namespace ConstExample
{
public class HasImmutableMember
{
// static private double fSectionLengthTolerancePerInch = 1 / (20 * 12); // tolerance is 1" per every 20'
private const double fSectionLengthTolerancePerInch = 1 / (20 * 12); // tolerance is 1" per every 20'
static HasImmutableMember()
{
Console.WriteLine("static c'tor: " + fSectionLengthTolerancePerInch);
}
public HasImmutableMember()
{
Console.WriteLine("instance c'tor: " + fSectionLengthTolerancePerInch);
}
}
public class Program
{
public void Main(string[] args)
{
HasImmutableMember instance = new HasImmutableMember();
}
}
}
Console output is:
static c'tor: 0
instance c'tor: 0
Can't set a breakpoint at the const member declaration, but if I use the static version, I can. Both fail to give me what I want. The static member declaration does get hit prior to either the static c'tor or the instance c'tor. And as expected the static c'tor gets hit before the instance c'tor. But in both the static and instance c'tor's the value of my member is 0 rather than the initialized value.
What am I missing?
Upvotes: 0
Views: 224
Reputation: 62
change
private const double fSectionLengthTolerancePerInch = 1 / (20 * 12);
to
private const double fSectionLengthTolerancePerInch = 11.0
Upvotes: -2
Reputation: 660159
This is a classic "conversion too late" defect which I wish the C# compiler warned about. You are doing all the arithmetic in integers, and then assigning the result to a double. The result is an integer, and 1 / 240
in integers is zero. Do the arithmetic in doubles: 1.0 / 240.0
.
We also see this defect involving non-constants, eg,
percentDone = doneSoFar / totalWork;
If the dividends are integers and the result is a double then the result is likely to be zero.
Also watch out for the same "conversion too late" defect involving multiplication:
double microseconds = seconds * 1000000;
if seconds
is int and more than a couple thousand then this will overflow in integers before it assigns to double, instead of what you want, which is to convert to double first and do the multiplication in doubles. Again, it should be 1000000.0
to hint to the compiler that you wish the operation to be done in higher precision.
Upvotes: 5
Reputation: 15320
You need to cast at least one of your integers since you are dividing two integers and this results in an integer as well (which gets rounded to 0 in your case):
private const double fSectionLengthTolerancePerInch = (double)1 / (20 * 12);
And then you can use:
Console.WriteLine("instance c'tor: " + fSectionLengthTolerancePerInch);
>>> 0.00416666666666667
Upvotes: 0
Reputation: 8318
Reason is that there is Integer division
.
When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded.88) If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.
Try following .
private const double fSectionLengthTolerancePerInch = 1.0 / (20 * 12);
Upvotes: 1
Reputation: 8782
You operate on integers 1 / (20 * 12)
. The result is actually 0
. You have to have at least one number to be double to get the result as double: 1.0 / (20 * 12)
.
Upvotes: 0