Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

if ((123 / 1000) > 0) returns false [duplicate]

Tags:

c#

numbers

I recently came across what seems to puzzle my logic of maths in a piece of code

if((123/1000) > 0)

For some reason, C# is claiming that this is false but if one were to think logically, 0.123 is larger than 0.

Is there any reason that it is claiming that 0.123 is smaller than 0?

I have read that there will be a comparison issue with double that is base 2 and it would be better to use decimal which is base 10.

Could someone enlighten me?

like image 263
Muhammad Aljunied Avatar asked Mar 20 '13 07:03

Muhammad Aljunied


3 Answers

Your fallacy is that you think the result is 0.123 whereas it is 0 instead.

C# (and many other C-like languages) define that operations involving two integral numbers always return an integer, so 1 + 1 will return 2, not 2.0 and 3 / 2 will return 1, not 1.5. The fractional part in this case is simply discarded, so it always rounds towards zero (i.e. for positive results it rounds down, for negative ones it rounds up).

While this is perhaps a little counter-intuitive the main reason for this is language/compiler simplicity, execution speed (because you do not need to figure out what type the result has), the ability to use operators like /= which wouldn't work if the result was a different type) and historical legacy and inertia.

To solve this you need to make at least one of your operands a floating-point number (the other one will follow suit automatically, as will the result):

// either
if (123.0 / 1000 > 0)
// or
if (123 / 1000.0 > 0)
// or
if (123.0 / 1000.0 > 0)

If you have variables instead you may need a typecast (as you cannot simply append .0 :-)):

if ((double)a / b > 0)

And the usual advice holds true here as well: When programming, rarely trust your intuition because computers are strange machines and programming languages sometimes even stranger. Printing the result somewhere or assigning it to a variable and checking in the debugger would have shown you that your expectations were off :-)

like image 119
Joey Avatar answered Sep 25 '22 08:09

Joey


123 and 1000 are integers, and the result is less than 1 so it's rounded to 0. Use this:

123.0/1000.0 > 0.0

And it will use double-precision, i.e. you can have a fraction!

like image 40
Kieren Johnstone Avatar answered Sep 22 '22 08:09

Kieren Johnstone


Since 123 and 1000 are Int32, result must be Int32. But since the result is less than 1, it is automatically rounded to 0.

You shoud make at least of this numbers is floating-point numbers.

if(123.0/1000.0 > 0.0)
{
   if((123.0/1000) > 0)
   {
       if((123/1000.0) > 0)
       {
             Console.WriteLine("True"); // Prints True
       }
   }
}

Here is a DEMO.

Check out this question also Possible Loss of Fraction

like image 45
Soner Gönül Avatar answered Sep 23 '22 08:09

Soner Gönül