Double -> Integer

A

Armin Zingler

Hi,

is there a function in the Framework that cuts the places
after the decimal point of a Double and converts to an Integer
_without_ performing any rounding (as Convert.ToInt32 does)?
I mean, what the IL code "conv.i4" does? ATM I'm using a function
that exactly does what I need in a C++ helper library:

static int ToInt32(double value)
{
return int(value);
};

But I want to get rid of it because a whole library for this
function is oversized and because this simple function should be
in the Framework, shouldn't it?
 
T

Tom Shelton

Armin Zingler submitted this idea :
Hi,

is there a function in the Framework that cuts the places
after the decimal point of a Double and converts to an Integer
_without_ performing any rounding (as Convert.ToInt32 does)?
I mean, what the IL code "conv.i4" does? ATM I'm using a function
that exactly does what I need in a C++ helper library:

static int ToInt32(double value)
{
return int(value);
};

But I want to get rid of it because a whole library for this
function is oversized and because this simple function should be
in the Framework, shouldn't it?

Well... Math.Truncate? You would of course have to case the return to
an integer..
 
A

Armin Zingler

Am 10.01.2011 23:20, schrieb Tom Shelton:
Armin Zingler submitted this idea :

Well... Math.Truncate? You would of course have to case the return to
an integer..

Yes, but how to convert then?
 
T

Tom Shelton

After serious thinking Armin Zingler wrote :
Am 10.01.2011 23:20, schrieb Tom Shelton:

Yes, but how to convert then?

I don't understand?

Module Module1

Sub Main()
Dim d As Double = 7.9999999
Dim i As Integer = CInt(Math.Truncate(d))
Console.WriteLine(i)
End Sub

End Module

output = 7
 
A

Armin Zingler

Am 11.01.2011 01:36, schrieb Tom Shelton:
After serious thinking Armin Zingler wrote :

I don't understand?

Module Module1

Sub Main()
Dim d As Double = 7.9999999
Dim i As Integer = CInt(Math.Truncate(d))
Console.WriteLine(i)
End Sub

End Module

output = 7

CInt perform rounding. That's what I want to avoid because it's unnecessary
and costs time. It's unnecessary because Truncate has been called before.
 
A

Armin Zingler

Am 11.01.2011 01:36, schrieb Tom Shelton:
The code above emitts:

conv.i4

whereas CInt just calls Convert.ToInt32, and it's IL code is:

---------->

.locals init (int32 V_0,
float64 V_1,
int32 V_2,
float64 V_3)
IL_0000: ldarg.0
IL_0001: ldc.r8 0.0
IL_000a: blt.un.s IL_0043
IL_000c: ldarg.0
IL_000d: ldc.r8 2147483647.5
IL_0016: bge.un.s IL_007a
IL_0018: ldarg.0
IL_0019: conv.i4
IL_001a: stloc.0
IL_001b: ldarg.0
IL_001c: ldloc.0
IL_001d: conv.r8
IL_001e: sub
IL_001f: stloc.1
IL_0020: ldloc.1
IL_0021: ldc.r8 0.5
IL_002a: bgt.s IL_003d
IL_002c: ldloc.1
IL_002d: ldc.r8 0.5
IL_0036: bne.un.s IL_0041
IL_0038: ldloc.0
IL_0039: ldc.i4.1
IL_003a: and
IL_003b: brfalse.s IL_0041
IL_003d: ldloc.0
IL_003e: ldc.i4.1
IL_003f: add
IL_0040: stloc.0
IL_0041: ldloc.0
IL_0042: ret
IL_0043: ldarg.0
IL_0044: ldc.r8 -2147483648.5
IL_004d: blt.un.s IL_007a
IL_004f: ldarg.0
IL_0050: conv.i4
IL_0051: stloc.2
IL_0052: ldarg.0
IL_0053: ldloc.2
IL_0054: conv.r8
IL_0055: sub
IL_0056: stloc.3
IL_0057: ldloc.3
IL_0058: ldc.r8 -0.5
IL_0061: blt.s IL_0074
IL_0063: ldloc.3
IL_0064: ldc.r8 -0.5
IL_006d: bne.un.s IL_0078
IL_006f: ldloc.2
IL_0070: ldc.i4.1
IL_0071: and
IL_0072: brfalse.s IL_0078
IL_0074: ldloc.2
IL_0075: ldc.i4.1
IL_0076: sub
IL_0077: stloc.2
IL_0078: ldloc.2
IL_0079: ret
IL_007a: ldstr "Overflow_Int32"
IL_007f: call string System.Environment::GetResourceString(string)
IL_0084: newobj instance void System.OverflowException::.ctor(string)
IL_0089: throw
<----------


You see the difference between what's required and what's done? :)
 
R

runningOnEmpty

runningOnEmpty submitted this idea :

Not if you have option strict on.

Fair enough, given that cint seems a throwback to vb6 then:

Dim i As Integer = CType(Math.Truncate(d), integer) '?
 
T

Tom Shelton

Armin Zingler explained on 1/10/2011 :
Am 11.01.2011 01:36, schrieb Tom Shelton:

CInt perform rounding. That's what I want to avoid because it's unnecessary
and costs time. It's unnecessary because Truncate has been called before.

I realize that, but there is no direct way that I know of in VB. If
you have option strict on, that is...
 
T

Tom Shelton

runningOnEmpty brought next idea :
Fair enough, given that cint seems a throwback to vb6 then:

Dim i As Integer = CType(Math.Truncate(d), integer) '?

That just converts to essentially what I had, when you get to the il.
No reason not to use CInt - since that's what you mean.
 
A

Armin Zingler

Am 11.01.2011 01:55, schrieb runningOnEmpty:
Works without the CInt function, it seems redundant here.


Neither CInt nor Truncate is redundant:

- Only Math.Truncate() wouldn't work because of a type mismatch.
Do you know which kind of conversion is done internally if
Option Strict is Off? I do not. Therefore, Option Strict On makes
you think about it and convert as intended.

- Only CInt() gives not the same results as CInt(Math.Truncate()),
e.g. CInt(0.6) = 1 whereas CInt(Math.Truncate(0.6)) is 0.


I'm currently at a little tool showing the differences in a table.
(because I'm unable to remember...) I've just added the Truncate function:

http://www.abload.de/image.php?img=double2integerfunction1ncm.png

The first column is the value to be converted.

For each line the rules are:
- Same background color = same data type
- Same foreground color = same value

(the exe also shows negative values not shown in the screenshot)
 
A

Armin Zingler

Am 11.01.2011 02:17, schrieb Tom Shelton:
I realize that, but there is no direct way that I know of in VB. If
you have option strict on, that is...

Yes, not in VB, but obviously not in the Framework, too. Such a simple task... ^^
Anyway, thanks.
 
A

Armin Zingler

Am 11.01.2011 02:13, schrieb runningOnEmpty:
Fair enough, given that cint seems a throwback to vb6 then:

Dim i As Integer = CType(Math.Truncate(d), integer) '?

CType(double , Integer) is the same as CInt (double).

Why "throwback"? Anyway, if you meant to leave out Math.Truncate
(not leave out Cint), I don't see a problem even with Strict On.
 
A

Armin Zingler

Am 11.01.2011 02:13, schrieb runningOnEmpty:
Fair enough, given that cint seems a throwback to vb6 then:

Dim i As Integer = CType(Math.Truncate(d), integer) '?

BTW, with Option Strict Off, Math.Round(d) is called, followed
by a conversion to Integer:

Dim d As Double = 7.9999R
Dim i As Integer = d


IL code:

IL_0009: ldc.r8 7.9999000000000002
IL_0012: stloc.0
IL_0013: ldloc.0
IL_0014: call float64 [mscorlib]System.Math::Round(float64)
IL_0019: conv.ovf.i4
IL_001a: stloc.1
 
N

Nobody

Here you go:

Dim d As Double = 7.9999999
Dim i As Integer = CInt(Int(d))

Console.WriteLine(i)

Output:

7

Int() function returns the same data type as the input, so it's necessary to
use CInt() to convert it to Integer.
 
R

runningOnEmpty

Armin Zingler explained on 1/10/2011 :

I realize that, but there is no direct way that I know of in VB. If you
have option strict on, that is...

I may be misreading this, in my test in VS2008 with strict on both CInt
and CType return the whole part of the double without any rounding.
 
N

Nobody

runningOnEmpty said:
I may be misreading this, in my test in VS2008 with strict on both CInt
and CType return the whole part of the double without any rounding.

No, it rounds, example:

Dim d As Double = 7.9999999
Dim i As Integer = CInt(d)

Console.WriteLine(i)

Output:

8
 
A

Armin Zingler

Am 11.01.2011 02:40, schrieb Nobody:
Here you go:

Dim d As Double = 7.9999999
Dim i As Integer = CInt(Int(d))

Console.WriteLine(i)

Output:

7

Int() function returns the same data type as the input, so it's necessary to
use CInt() to convert it to Integer.

Thank you, but as I underlined it in my first post, I want to convert to Integer
without rounding. CInt does perform rounding. Rounding is unnecessary after
calling Int().
 
R

runningOnEmpty

No, it rounds, example:

You are, of course, correct, given the statement:

"CInt perform rounding."

That big period should have been something of a clue ;)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top