12

I've stumbled upon an issue with CInt and converting a double to an integer.

The issue is the following:

CInt(10.5)  'Result is 10
CInt(10.51) 'Result it 11, but I expected 10...

I got used to C# style conversion where (int) 10.51 is 10.

As pointed out in the question about Integer.Parse vs CInt, the result is just rounded in some fashion.

However, all I need is to get only integer part and throw away the fractional one. How can I achieve such type of conversion in VB.NET? After some research I see that I can use the Fix() function to do the trick, but is it the best choice?

Community
  • 1
  • 1
nbulba
  • 645
  • 2
  • 7
  • 17
  • 2
    Worse: cint(10.5) = 10 but cint(11.5) = 12. if the integer part is even rounding of .50000000 is down, for odd it is up! – Martin Oct 07 '11 at 18:57

3 Answers3

9

You may use Int or Fix functions but return value type of these functions is double so you have to convert it to Integer if option strict is on.

  no = Convert.ToInt32(Int(10.51))
KV Prajapati
  • 93,659
  • 19
  • 148
  • 186
6

Firstly, your assumption that CInt is equivalent to (int) in C# is incorrect.

Secondly, the rounding behaviour of CInt is not randomly assigned - it actually uses "bankers rounding":

Fractional Parts. When you convert a nonintegral value to an integral type, the integer conversion functions (CByte, CInt, CLng, CSByte, CShort, CUInt, CULng, and CUShort) remove the fractional part and round the value to the closest integer.

If the fractional part is exactly 0.5, the integer conversion functions round it to the nearest even integer. For example, 0.5 rounds to 0, and 1.5 and 2.5 both round to 2. This is sometimes called banker's rounding, and its purpose is to compensate for a bias that could accumulate when adding many such numbers together.

The best equivalent to using (int) in C# is the Fix function in the VisualBasic namespace which rounds towards zero (same as Math.Truncate).

This however returns a Double value so you have to do a further conversion to get to your integer using CInt.

CInt(Fix(10.5)) '10
CInt(Fix(10.51)) '10
CInt(Fix(11.5)) '11
CInt(Fix(-10.5)) '-10
CInt(Fix(-10.51)) '-10
CInt(Fix(-11.5)) '-11
Matt Wilko
  • 26,994
  • 10
  • 93
  • 143
1

I think you can try CInt(Math.Floor(10.51)) hope this helps

Ginka
  • 560
  • 5
  • 14
  • 4
    Be aware that for a negative number, this might not give the expected result: `Math.Floor(-10.51)` is `-11`. If you want `-10`, you can use `Math.Truncate`. – Jeff B Dec 16 '14 at 16:02