If ((123/1000)> 0) returns false

I recently came across something that seems to puzzle my math logic in a piece of code

if((123/1000) > 0) 

For some reason, C # claims to be a lie, but if you think logically, 0.123 is greater than 0.

Is there any reason he claims 0.123 is less than 0?

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

Can anyone enlighten me?

+6
source share
7 answers

Your mistake is that you think the result is 0.123 , whereas 0 .

C # (and many other C-like languages) determines that operations with two integers always return an integer, so 1 + 1 will return 2 , not 2.0 and 3/2 will return 1 , not 1.5 . In this case, the fractional part is simply discarded, therefore it is always rounded to zero (i.e., it is rounded for positive results, rounded for negative results).

Although this is perhaps a little contrary to intuition, the main reason for this is the simplicity of the language / compiler, the speed of execution (because you do not need to determine what type of result it has), the ability to use operators such as /= which will not work if the result is different type) and historical heritage and inertia.

To solve this problem, you need to make at least one of your operands a floating point number (the other will automatically follow it, as well as 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, you might need typecast (since you can't just add .0 : -)):

 if ((double)a / b > 0) 

And the usual recommendations here are true: when programming, rarely trust your intuition, because computers are strange machines and programming languages, sometimes even unfamiliar ones. Listing the result somewhere or assigning it to a variable and checking it in the debugger would show that your expectations were not :-)

+15
source

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

 123.0/1000.0 > 0.0 

And he will use double precision, i.e. you can have a share!

+9
source

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

You can make at least a floating point number from these 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 the DEMO .

Check this question and Possible fraction loss.

+4
source

Despite the fact that this was answered, no one gave a good point of view on this problem, so I wanted to make it more clear:

If you are dividing or multiplying int and float , you will get the following results:

 int/int => int float/int => float int/float => float 

so if you split:

 123/1000 => 0 (as there is no int number 0.123, it will then set to 0) 123.0/1000 => 0.123 (this dividing is basically saying that I need a float result of dividing) 123/1000.0 => 0.123 (this says the same as previous) 

So, the rule is basically - if you use a type that is at the "upper" level, the one that is used, then the calculation will be transferred to this "parent" type. But this cannot be said at all, as if a floating type were used, it would always be passed to a floating-point number. Here are some more examples:

 long/int => long double/float => double double/int => double 

And if you want to have an answer to your question, the answer would be to put:

 if(((float)123/1000) > 0) 

or

 if(((double)123/1000) > 0) 

This way it will always calculate the floating point number (0.123)

+2
source

int / int is int - this means 123/1000 is 0 , not 0.123 , as you might expect -

since 0 is not greater than 0, the expression evaluates to false!

The fix is ​​to make one of the integers double -

 if(123.0 / 1000 > 0) <- true if(123 / 1000.0 > 0) <- true if(123.0 / 1000.0 > 0) <- true 
+1
source

Use this:

 if((123.0/1000) > 0) 

You are trying to split int to int . This way you get integer division. But you need to use double.

And if you want to share internal variables and get double use:

  double doubleNum = (double)intNum1/(double)intNum2; 
0
source

When splitting with integer values, the result will also be an integer.

If I recall correctly, the part after the decimal point is removed.

So, your code compiles into something like:

 a = int(123/1000) <--- evaluates to 0. if (a > 0) .... <--- false 

The solutions according to @algreat's answer is to force one of the operands to be double (by adding .0 . This will make the result also swim.

-1
source

All Articles