-3

Perhaps I have spent one too many nights up late, but I had the following code :

MessageBox.Show(
  Convert.ToInt32(
    Math.Round(
      (double)( ( i+1 )/r.Count )*100 ,
      0
    )
  ).ToString()
);

Which always returns 0, even when i=120000 and r.Count=150000. This is a simple progress calculation where i is the current iteration in the loop, and r is the collection ( List() ).

I have separated the code, and even the following still returns 0 :

Convert.ToInt32( 
           Math.Round( 
                      (double)(( 120000+1 )/167428 )*100
                      , 0 )
                )

Not sure whats going on here so any insight as to what I am doing wrong (probably a forehead slapper). It should be (using above numbers), returning 71.

@Habib's flag as duplicate :

that duplicate you claim -- is actually different, even the solutions don't apply here as this was a casting issue to double, and not adding 'm' with additional decimal points to each variable in play.

Kraang Prime
  • 9,981
  • 10
  • 58
  • 124
  • so what you guys are saying (reading answers below), is that I need to cast the integers both to double first, and that .NET doesn't do any magic when using mathematical operations (eg, float the number if divising two integers when needed) ? – Kraang Prime Jul 09 '15 at 17:11
  • no just casting one will do, but do it before division not after. – Chaitanya Gadkari Jul 09 '15 at 17:14
  • @SanuelJackson It can't guess what you want, and in some cases integer division *is* what you want. So no, it doesn't do magic. – Borgleader Jul 09 '15 at 17:14
  • Got it. Makes sense. Adding a footnote, this wasn't as much of a forehead slapper as I thought it would be -- the math was technically correct, just the values weren't auto-converting to double. Easy fix, but this is one of those moments I was expecting .NET to take care of more than it actually does :) . – Kraang Prime Jul 09 '15 at 17:17
  • lol. love the downers tho. -.- ... like why down-vote when the question is legit, and clear. sometimes this boggles me as to why people down-vote easy questions (or difficult ones). PS --- that duplicate you claim Habib -- is actually different, even the solutions don't apply here as this was a casting issue to `double`, and not adding 'm' with additional decimal points to each variable in play. – Kraang Prime Jul 09 '15 at 17:19

7 Answers7

9

Because ( 120000+1 )/167428 is still being done using integer math. Instead of ~0.716, it's 0.

If you want to avoid this in the future, make sure you're casting the numerator and denominator to a double as well.

( (double)( i+1 )/(double)r.Count )*100
Michael Dunlap
  • 4,300
  • 25
  • 36
4

You are casting to double after doing integer division.

Matt Eckert
  • 1,946
  • 14
  • 16
3

The following will evaluate to ( 120000+1 )/167428 ) to 0 as they are int's and do not keep decimal precision, try this

Convert.ToInt32(Math.Round(((double)(120000+1 ) / (double)167428 ) * 100))
Marko
  • 2,734
  • 24
  • 24
2

this is related to implicit conversion

https://msdn.microsoft.com/en-us/library/ms173105.aspx

the operation: (120000+1)/167428 returns an integer as result, 0. you are casting double after doing this integer division.

like other users suggest try casting the values:

  (double)(( (float)120000f+1 )/(float)167428f )*100
Jorgesys
  • 124,308
  • 23
  • 334
  • 268
  • Really, referencing a java doc for a C# question? – leppie Jul 09 '15 at 17:17
  • Why not the concept is the same, probably your knowledge is only C# or .net technologies. – Jorgesys Jul 09 '15 at 17:21
  • And? There has already been 5 other answers saying that. Misleading redirection is foul. But I see you at least fixed it. Thanks. – leppie Jul 09 '15 at 17:24
  • "hasta Lo que no se tragan les hace daño", ok so merg a chuparselas si come rahat! :) thak you. – Jorgesys Jul 09 '15 at 17:37
  • 1
    XD .. nice. I upvoted for the research. Also noticed you changed to MSDN link which is cool. Just like to point out, if using `f`, then don't need to cast using `(float)`. – Kraang Prime Jul 09 '15 at 17:39
0

(( 120000+1 )/167428 ) will evaluate to 0

167428 does not go into 120001. what you can try is this:

Convert.ToInt32( 
       Math.Round( 
                  (((double)120000f+(double)1f )/(double)167428f )*(double)100f
                  , 0 )
            )
maraaaaaaaa
  • 7,749
  • 2
  • 22
  • 37
0

If r.Count > i+1, then (i+1) / r.Count will give you a zero. Both are integers and so anything after the decimal point gets cut off.

You probably mean to cast either i+1 or r.Count to double, then you'll get the answer you expect.

Eg:

(i+1) / (double)r.Count

HughHughTeotl
  • 5,439
  • 3
  • 34
  • 49
0

Try this:

You have to convert one of the two values to double before you divide.

Convert.ToInt32( 
           Math.Round( 
                      (((double)( 120000+1 ))/167428 )*100
                      , 0 )
                )
whymatter
  • 755
  • 8
  • 18