Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cleanest way to convert a `Double` or `Single` to `Integer`, without rounding

Converting a floating-point number to an integer using either CInt or CType will cause the value of that number to be rounded. The Int function and Math.Floor may be used to convert a floating-point number to a whole number, rounding toward negative infinity, but both functions return floating-point values which cannot be implicitly used as Integer values without a cast.

Is there a concise and idiomatic alternative to IntVar = CInt(Int(FloatingPointVar));? Pascal included Round and Trunc functions which returned Integer; is there some equivalent in either the VB.NET language or in the .NET framework?

A similar question, CInt does not round Double value consistently - how can I remove the fractional part? was asked in 2011, but it simply asked if there was a way to convert a floating-point number to an integer; the answers suggested a two-step process, but it didn't go into any depth about what does or does not exist in the framework. I would find it hard to believe that the Framework wouldn't have something analogous to the Pascal Trunc function, given that such a thing will frequently be needed when performing graphical operations using floating-point operands [such operations need to be rendered as discrete pixels, and should be rounded in such a way that round(x)-1 = round(x-1) for all x that fit within the range of +/- (2^31-1); even if such operations are rounded, they should use Floor(x+0.5), rather than round-to-nearest-even, so as to ensure the above property]

Incidentally, in C# a typecast from Double to Int using (type)expr notation uses round-to-zero semantics; the fact that this differs from the VB.NET behavior suggests that one or both languages is using its own conversion routines rather an explicit conversion operator included in the Framework. It would seem likely that the Framework should define a conversion operator? Does such an operator exist within the framework? What does it do? Is there a way to invoke it from C# and/or VB.NET?

like image 390
supercat Avatar asked Feb 04 '13 17:02

supercat


2 Answers

After some searching, it seems that VB has no clean way of accomplishing that, short of writing an extension method.

The C# (int) cast translates directly into conv.i4 in IL. VB has no such operators, and no framework function seems to provide an alternative.

Usenet had an interesting discussion about this back in 2005 – of course a lot has changed since then but I think this still holds.

like image 102
Konrad Rudolph Avatar answered Sep 29 '22 21:09

Konrad Rudolph


You can use the Math.Truncate method.

Calculates the integral part of a specified double-precision floating-point number.

For example:

Dim a As double = 1.6666666
Dim b As Integer = Math.Truncate(a) ' b = 1
like image 42
Styxxy Avatar answered Sep 29 '22 20:09

Styxxy