Float to int conversion error

R

Richard Thrasher

Writing my very first C# program, I found what appears to
be a compiler error. The statement
int temp = (int)(100 * 36.41);
assigns the value 3640 to temp. I've tried this code with
various numbers in place of 36.41, but 36.41 is the only
number I've found that produces the error.

My questions are:
(1) Can anybody else reproduce this error?
(2) How does one submit bug reports to MS?
 
M

Michael Culley

This is a common problem with floating point values and is really a limitation instead of a bug. This problem is common to all
languages that use floating point values. It is even a limitation in the maths co processor in your cpu. When C# converts the value
to an integer it must just round down, so if the value is stored as 3640.99999 then it becomes 3640. You can use Convert.ToInt32 to
get the correct value.
 
M

Michael A. Covington

Richard Thrasher said:
Writing my very first C# program, I found what appears to
be a compiler error. The statement
int temp = (int)(100 * 36.41);
assigns the value 3640 to temp. I've tried this code with
various numbers in place of 36.41, but 36.41 is the only
number I've found that produces the error.

My questions are:
(1) Can anybody else reproduce this error?
(2) How does one submit bug reports to MS?

Well... You may have blundered into one of the big "gotchas" of computer
programming as we know it.

36.41 is a number that cannot be expressed exactly in binary, for the same
reason that 1/3 cannot be expressed exactly in decimal. (It would take an
infinite number of decimal places or binary places respectively.)

So when you write "36.41" you actually get a binary number very slightly
less than 36.41.

Then you multiply it by 100 and get 3640.9999999 or something like that.

Then you convert -- and if the int conversion is done by truncation, you get
3640.

At least that's my educated guess about what's happening.

The Microsoft "Decimal" numeric type overcomes this; it's actually
represented in decimal, so 36.41 is always exactly 36.41.
 
J

Jeff Ogata

If you don't cast to int, and try this:

double temp = 100 * 36.41;

you'll find that temp is 3640.9999999999995

As Jon Skeet pointed out to me earlier, the cast to int rounds down to 0,
while a Convert.ToInt32 will round to the nearest integer. If you try

int temp = Convert.ToInt32(100 * 36.41);

you'll find that temp is 3641

HTH,
Jeff
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top