Reputation: 2685
I have the static method GetFraction
which returns the cents in a price as below:
public static class PriceUtil
{
public static int GetFraction(float price)
{
int PriceInt = (int)(100 * price);
return PriceInt % 100;
}
}
For the price $23.79, this method returns 78 Cents instead of 79. While debugging, I fixed the bug unintentionally as follows:
public static class PriceUtil
{
public static int GetFraction(float price)
{
float PriceFloat = 100 * price;
int PriceInt = (int)(PriceFloat);
return PriceInt % 100;
}
}
I don't understand why assigning the (100 * price) to a float variable solves the problem. AFAIK, casting to integer is applied to exactly same value as int
times float
is float
anyways.
Thanks in advance for your replies!
Upvotes: 0
Views: 257
Reputation: 106826
As it has been noted in the comments you should be using decimal
as the type instead of float
to avoid this kind of problem.
Using the value 23.79f
does not exhibit the problem you describe on my computer so my guess is that the price has been computed by some previous calculation. Here is a demonstration:
var value = 23.7899999f;
Console.WriteLine(value);
var fraction = ((int) (value*100))%100;
Console.WriteLine(fraction);
The output of this code is
23.79 78
Another possibility of the problem you experience is that float
is a 32 bit floating point number and internally on the CPU calculations are often performed using 80 bit floating point numbers. If you change the way you perform your calculations you may see slightly different results depending on when the rounding or truncation is performed. However, I doubt that this is the explanation of the results that you experience.
You should be able to solve your problem by rounding the value before computing the fraction:
var value = 23.7899999f;
Console.WriteLine(value);
var roundedValue = Math.Round(value, 2);
var fraction = ((int) 100*roundedValue)%100;
Console.WriteLine(fraction);
The output is now
23.79 79
Upvotes: 1