I have this function I am writing.
const int ProgressBarLength = 230;
foreach (TransactionDetail item in list)
{
var itemProgress =
((ProgressBarLength/item.PurchasesRequired) *
Convert.ToInt32(item.TransactionAmount));
item.ProgressBar = itemProgress > ProgressBarLength ? ProgressBarLength : itemProgress;
}
Now I have 2 TransactionDetails in my loop.
If item.PurchasesRequired = 500 and TransactionAmount = 199.0 the resulting value is 0. However, if item.PurchasesRequired = 5 and TransactionAmount = 94.0 it returns a valid result.
What am I doing wrong?
Is item.PurchasesRequired an int?
If so, your problem is integer division.
ProgressBarLength is an int, so 230/500 = 0.
Use float, double, or decimal (either in a cast or for your ProgressBarLength) to maintain your desired level of precision.
I'm guessing you should do a cast to double somewhere to have more precision in your divisions. When dividing an int by an int, you won't get a double as result.
Try the following:
double itemProgress = ( ((double)ProgressBarLength / item.PurchasesRequired )
* Convert.ToInt32( item.TransactionAmount ) );
It looks like you're performing integer division.
230 / 500 is zero in integer division, whereas 230 / 5 is 46.
You can force floating-point division by casting PurchasesRequired to a double. 230 / 500 is 0.46 in floating-point division, as you'd expect.
const int ProgressBarLength = 230;
foreach (TransactionDetail item in list)
{
var itemProgress = ((ProgressBarLength / (double)item.PurchasesRequired)
* Convert.ToInt32(item.TransactionAmount));
item.ProgressBar = Math.Min((int)itemProgress, ProgressBarLength);
}
I'm guessing TransactionDetail.PurchaseRequired is a field or property of type int.
ProgressBarLength/item.PurchasesRequired divides an in by an int which results in an int, not a float. in your first example, 230 / 500 does integer division and the result is, of course, 0.
You can either calculate the expression as a double, or do the multiplication first so that you don't lose relevant precision from the integer division.
var itemProgress = (double) ProgressBarLength / item.PurchasesRequired * item.TransactionAmount;
or
var itemProgress = ProgressBarLength * (int) item.TransactionAmount / item.PurchasesRequired));
Related
Take the following code:
float a = 100.0f;
float b = 0.05f;
If I want to convert the result of division between a and b to an integer, I can do it with this code:
float c = a / (b * 1000.0f); // c = 2f
int res = (int)c; // res = 2
But I want to reduce the number of code lines, so I prefer to use this code instead:
int res = (int)(a / (b * 1000.0f)); // Here we are --> res = 1 !
Why with the last code I obtain res = 1 instead of res = 2 ?
The compiler uses extra precision when computing some expressions. In the C# language specification, clause 9.3.7 allows an implementation to use more precision in a floating-point expression than the result type:
Floating-point operations may be performed with higher precision than the result type of the operation.
Note that the value of .05f is 0.0500000007450580596923828125. When .05f * 1000.0f is computed with float precision, the result is 50, due to rounding. However, when it is computed with double or greater precision, the result is 50.0000007450580596923828125. Then dividing 100 by that with double precision produces 1.999999970197678056393897350062616169452667236328125. When this is converted to int, the result is 1.
In float c = a / (b * 1000.0f);, the result of the division is converted to float. Even if the division is computed with double precision and produces 1.999999970197678056393897350062616169452667236328125, this value becomes 2 when rounded to float, so c is set to 2.
In int res = (int)(a / (b * 1000.0f));, the result of the division is not converted to float. If the compiler computes it with double precision, the result is 1.999999970197678056393897350062616169452667236328125, and converting that produces 1.
This simple calculation is returning zero, I can't figure it out:
decimal share = (18 / 58) * 100;
You are working with integers here. Try using decimals for all the numbers in your calculation.
decimal share = (18m / 58m) * 100m;
18 / 58 is an integer division, which results in 0.
If you want decimal division, you need to use decimal literals:
decimal share = (18m / 58m) * 100m;
Since some people are linking to this from pretty much any thread where the calculation result is a 0, I am adding this as a solution as not all the other answers apply to case scenarios.
The concept of needing to do calculations on various types in order to obtain that type as a result applies, however above only shows 'decimal' and uses it's short form such as 18m as one of the variables to be calculated.
// declare and define initial variables.
int x = 0;
int y = 100;
// set the value of 'x'
x = 44;
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0.
Console.WriteLine( (x / y).ToString() );
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0. The conversion to double happens
// after the calculation has been completed, so technically this results
// in 0.0
Console.WriteLine( ((double)(x / y)).ToString() );
// Results in 0.44 as the variables are cast prior to calculating
// into double which allows for fractions less than 1.
Console.WriteLine( ((double)x / (double)y).ToString() );
Because the numbers are integers and you perform integer division.
18 / 58 is 0 in integer division.
Whenever I encounter such situations, I just upcast the numerator.
double x = 12.0 / 23409;
decimal y = 12m / 24309;
Console.WriteLine($"x = {x} y = {y}");
double res= (firstIntVar * 100f / secondIntVar) / 100f;
when dividing numbers I use double or decimal , else I am getting 0 , with this code even if firstIntVar && secondIntVar are int it will return the expected answer
decimal share = (18 * 100)/58;
Solved: working perfectly with me
int a = 375;
int b = 699;
decimal ab = (decimal)a / b * 100;
I'm trying to do a simple picee of maths where I work out if a value is between two values and if so, it does, it should do a simple division. However sometimes the value divided by are like 0.9, 0.6 etc and that always returns 0.
in this example,
int m_LocationSqrMtr = 4339;
float m_DefaultPricing = Convert.ToSingle(DefaultPricing);
float m_manDays;
if (m_LocationCosts > 450 && m_LocationCosts < 700)
{
m_DefaultPricing = 700 / m_LocationSqrMtr;
}
My guess is that the type of m_LocationSqrMtr is int, in which case this expression:
700 / m_LocationSqrMtr
... will be computed using integer arithmetic, and the result converted to float. I suspect you want:
if (m_LocationCosts > 450 && m_LocationCosts < 700)
{
m_DefaultPricing = 700f / m_LocationSqrMtr;
}
The f suffix on the literal means that it's a float literal, so first m_LocationSqrMtr will be promoted to float, and then the division performed using float arithmetic.
However, if this is meant to be representing currency values, you should consider using decimal instead of float - and then probably rounding the value to 2 decimal places. If you do all your currency arithmetic in decimal, you're less likely to run into unexpected results...
You have:
int m_LocationSqrMtr = 4339;
[...]
m_DefaultPricing = 700 / m_LocationSqrMtr;
That is, 700 / 4339, which is (integer) / (integer), the result of which is an integer.
I know you were expecting an answer of 0.16132....
But in integer terms, that value is ZERO.
If the type of m_LocationSqrMtr is int, as in a 32-bit whole number, then the expression
700 / m_LocationSqrMtr
is one integer divided by another integer, and it's type is integer. Only after this integer is produced is the result assigned to the float m_DefaultPricing, so basically your code is equivalent to:
int temp = 700 / m_LocationSqrMtr;
m_DefaultPricing = (float) temp;
If you want to force floating point arithmetic, at least one of the operands needs to be a floating point number. There are a number of ways that this can be done:
m_DefaultPricing = 700.0 / m_LocationSqrMtr; //explicit decimal point
m_DefaultPricing = 700f / m_LocationSqrMtr; //explicit float specification
m_DefaultPricing = (float)700 / m_LocationSqrMtr; //casting one operand
m_DefaultPricing = 700f / (float)m_LocationSqrMtr; //into a float
There are already a number of good practical answers so on a more conceptual level:
In C# if both sides of the operator are an integer the result is also an integer and any decimal digits are truncated. In general, for math, the language will produce a result of the same type as the input with the most precise type. The type of variable you store the result in will have no effect on the result only the types of the inputs.
By forcing one input to be decimal or float you force the output to be that as well. In practice you can either do this by declaring your one of your input variables as a decimal or float (depending on which you use, in your case you would change the type of m_LocationSqrMtr) or if you have a constant input (as you do) you can force it to be decimal/float/double as follows:
var a = 10f // float
var b = 10d // double
var c = 10m // decimal
var d = 10.0 // double I believe
This simple calculation is returning zero, I can't figure it out:
decimal share = (18 / 58) * 100;
You are working with integers here. Try using decimals for all the numbers in your calculation.
decimal share = (18m / 58m) * 100m;
18 / 58 is an integer division, which results in 0.
If you want decimal division, you need to use decimal literals:
decimal share = (18m / 58m) * 100m;
Since some people are linking to this from pretty much any thread where the calculation result is a 0, I am adding this as a solution as not all the other answers apply to case scenarios.
The concept of needing to do calculations on various types in order to obtain that type as a result applies, however above only shows 'decimal' and uses it's short form such as 18m as one of the variables to be calculated.
// declare and define initial variables.
int x = 0;
int y = 100;
// set the value of 'x'
x = 44;
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0.
Console.WriteLine( (x / y).ToString() );
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0. The conversion to double happens
// after the calculation has been completed, so technically this results
// in 0.0
Console.WriteLine( ((double)(x / y)).ToString() );
// Results in 0.44 as the variables are cast prior to calculating
// into double which allows for fractions less than 1.
Console.WriteLine( ((double)x / (double)y).ToString() );
Because the numbers are integers and you perform integer division.
18 / 58 is 0 in integer division.
Whenever I encounter such situations, I just upcast the numerator.
double x = 12.0 / 23409;
decimal y = 12m / 24309;
Console.WriteLine($"x = {x} y = {y}");
double res= (firstIntVar * 100f / secondIntVar) / 100f;
when dividing numbers I use double or decimal , else I am getting 0 , with this code even if firstIntVar && secondIntVar are int it will return the expected answer
decimal share = (18 * 100)/58;
Solved: working perfectly with me
int a = 375;
int b = 699;
decimal ab = (decimal)a / b * 100;
I have an integer (representing seconds) which I'm converting to hours by dividing by 3600. I then store the value in a property (type int). If the value contains a decimal point, I convert it by casting. However, when I try to assign the value to the property, I get an error: "Cannot implicitly convert type 'decimal' to 'int'." Here's my code:
var p = ((Hours.Duration) / 3600.0);
(Hours.Duration) = p;
However,
Hours.Duration = (Hours.Duration) / 3600
works fine, and rounds to an int. What am I doing wrong?
decimal p = ((Hours.Duration) / 3600);
(Hours.Duration) = p;
you are getting error because p is decimal and Hours.Duration is integer, You cannot assign decimal to int without explicit casting.
(Hours.Duration) = (int)p;
If Hours.Duration is integer, 3600 is also integer, then there will be an integer division, that is your decimal value will be lost. e.g. in integer division 7/2 =3. If you want the answer to be 3.5, then you need to have atleast one decimal number in the division i.e 7.0/2 = 3.5 OR 7/2.0 = 3.5.
Try:
Hours.Duration = Convert.ToInt32(p);
Don't define p as decimal. And the question is, if you want to include also partial hour (e.g. if the result for 4000/3600 would be 1 or 2). So you can write directly
Hours.Duration /= 3600;
or if you want count also partial hour
Hours.Duration = Hours.Duration / 3600 + ((Hours.Duration % 3600 > 0)?1:0);
or if you want correct rounding up
Hours.Duration = Hours.Duration / 3600 + ((Hours.Duration % 3600 >= 1800)?1:0);
You can use this code:
int vIn = 0;
double vOut = Convert.ToDouble(vIn);
Here is a very handy convert data type webpage for those of others: Convert decimal to int in C#