Reputation: 129
I am programming a stocks/production program for a school project (bike factory) and I have to round some numbers up such as the bikes that have to be produced (due to fallout it are doubles).
If I use the following code:
double test = Math.Ceiling(100 * 1.09);
label75.Text = Convert.ToString(test);
I get as an answer 110, but that's not right, it should be 109 (9% of 100). Although it seems to work with values below 9%.
What am I doing wrong?
Upvotes: 9
Views: 1054
Reputation: 149058
double
s and float
s are binary floating point types. This means they cannot precisely represent many decimal numbers (like 1.09
). This leads to some subtle round off errors. In your case 100 * 1.09 actually results in a number very slightly larger than 109, so the Ceiling
function correctly rounds it up to the nearest integer, 110.
Change it to a decimal
and you'll get the result you expect:
decimal test = Math.Ceiling(100 * 1.09m); // 109
Note the m
in 1.09m
identifies it as a decimal
literal. This works because the decimal
type is specifically designed to represent decimal numbers (rather than just their binary approximations, as double
and float
do).
Upvotes: 27
Reputation: 31196
Floating point arithmetic is not in base 10, it's in base 2. the double
type doesn't have an exact base-2 equivalent of 1.09
To illustrate, if you put a break-point at the end of the following program
public static void Main()
{
double test = 100 * 1.09;
}
than test
would show up as 109.00000000000001
Upvotes: 7