convert double to int
Asked Answered
D

13

200

What is the best way to convert a double to an int? Should a cast be used?

Disturbance answered 15/11, 2010 at 6:27 Comment(3)
define "best". depends if you want up/down rounding, etc.Garik
@RPM1984: Define etc. :)Hounding
@Armen - touche` :) Doesn't really matter anyway - Skeet is here, nothing else matters.Garik
P
280

You can use a cast if you want the default truncate-towards-zero behaviour. Alternatively, you might want to use Math.Ceiling, Math.Round, Math.Floor etc - although you'll still need a cast afterwards.

Don't forget that the range of int is much smaller than the range of double. A cast from double to int won't throw an exception if the value is outside the range of int in an unchecked context, whereas a call to Convert.ToInt32(double) will. The result of the cast (in an unchecked context) is explicitly undefined if the value is outside the range.

Polydipsia answered 15/11, 2010 at 6:30 Comment(8)
I am wondering if in 64 bits machine, Convert.ToInt32 is not OK any more?Disturbance
@user: The size of an int is always 32 bits, regardless of whether you're using a 32 or 64 bit machine.Pa
And doubles can be much huger than even a 64 bit int.Silda
For C# noobs like me: both Math and Convert are part of System. So the complete answer looks like this : intVal = System.Convert.ToInt32(System.Math.Floor(dblVal));Feud
@user1290746: That would work, but you'd usually just have using System; at the top of the file, at which point it could just be intVal = Convert.ToInt32(Math.Floor(dblVal));Polydipsia
Obviously that is obvious to anyone familiar with C#. And someone searching for an answer about type conversion is possibly/likely completely unfamiliar with the language - that was the case for me anyway - so thanks for your extra info.Feud
@user1290746: But in that case, I don't think the right solution is to advise people to use the fully-qualified names - the better solution is to learn about using directives.Polydipsia
Interesting that in VB.Net Double to Integer cast like CInt(Double) compiles to the default Math.Round(Double) call and conv.ovf.i4, but in C# (int)double compiles to conv.i4. In VB.Net CInt(1.5) is 2, but in C# (int)1.5 is 1.Most
N
52

Yeah, why not?

double someDouble = 12323.2;
int someInt = (int)someDouble;

Using the Convert class works well too.

int someOtherInt = Convert.ToInt32(someDouble);
Naraka answered 15/11, 2010 at 6:29 Comment(2)
Important to note: If someDouble was 12323.5, the (int) and Convert.ToInt32 conversions would give different results.Isadoraisadore
Good point. It appears to do banker's rounding (rounding to even), implementation appears to do so. Convert.cs Whereas casting simply truncates the decimal part out.Naraka
H
44

if you use cast, that is, (int)SomeDouble you will truncate the fractional part. That is, if SomeDouble were 4.9999 the result would be 4, not 5. Converting to int doesn't round the number. If you want rounding use Math.Round

Hounding answered 15/11, 2010 at 6:30 Comment(0)
D
8

The best way is to simply use Convert.ToInt32. It is fast and also rounds correctly.

Why make it more complicated?

Daggna answered 30/5, 2013 at 1:59 Comment(1)
You are right. The only important point to pay additional attention is what Jon Skeet has written: "Don't forget that the range of int is much smaller than the range of double"Johannesburg
W
6

Convert.ToInt32 is the best way to convert

Woodland answered 15/11, 2010 at 6:30 Comment(1)
This a typically unsafe function because it accepts just anything.Rooster
N
3

My ways are :

 - Convert.ToInt32(double_value)
 - (int)double_value
 - Int32.Parse(double_value.ToString());
Notornis answered 15/11, 2010 at 6:37 Comment(3)
Don't you think the third way is unnecessarily complex and slow?Hounding
The third will not work with doubles with fractional parts. e.g., double_value = 0.1Naraka
I think u can use Math.Floor.Nerve
A
3

None of the code samples exhibit the normal behaviour a school kid would expect (that halves are rounded up). What most people would expect is is this:

double d = 1.5;
int i = (int)Math.Round(d, MidpointRounding.AwayFromZero);
Aggiornamento answered 20/8, 2021 at 9:1 Comment(0)
C
1

Here is a complete example

class Example 
{    
  public static void Main() 
  {    
    double x, y; 
    int i; 

    x = 10.0; 
    y = 3.0; 

    // cast double to int, fractional component lost (Line to be replaced) 
    i = (int) (x / y); 
    Console.WriteLine("Integer outcome of x / y: " + i); 
  }    
}

If you want to round the number to the closer integer do the following:

i = (int) Math.Round(x / y); // Line replaced
Chatelain answered 15/11, 2010 at 7:26 Comment(0)
F
1

There is no better. It really depends on what you want, performance, accuracy, etc.

But see differences https://dotnetfiddle.net/kwqF2M

double testeDouble_min = 12.3456;
double testeDouble_max = 12.8456;
double emptyDouble;

int i01_min = Convert.ToInt32(testeDouble_min); //12
int i01_max = Convert.ToInt32(testeDouble_max); //13
//var erro = Convert.ToInt32(emptyDouble); //error  

int i02_min = (int)testeDouble_min; //12
int i02_max = (int)testeDouble_max; //12
//var erro = (int)emptyDouble; //error  

var styles = System.Globalization.NumberStyles.Integer | System.Globalization.NumberStyles.AllowDecimalPoint;
var provider = new System.Globalization.CultureInfo("en-US");
bool success = int.TryParse(testeDouble_min.ToString(), styles, provider, out int i03_min); //0

_ = int.TryParse(testeDouble_max.ToString(),  out int i03_max); //0 because it has decimal place, if it didn't have ok

int i04_min = (int)Math.Round(testeDouble_min, MidpointRounding.AwayFromZero); //12
int i04_max = (int)Math.Round(testeDouble_max, MidpointRounding.AwayFromZero); //13

About IL there are no big differences between (int) or Convert.ToInt32

var dd = 12.3;
int a = (int)dd;

result:

    IL_0000: nop
    IL_0001: ldc.r8 12.3
    IL_000a: stloc.0
    IL_000b: ldloc.0
    IL_000c: conv.i4
    IL_000d: stloc.1
    IL_000e: ret

(int) in theory less instructions tend to be faster, but I doubt anyone can measure that.

And

var dd = 12.3;
int b = Convert.ToInt32(dd);

result:

    IL_0000: nop
    IL_0001: ldc.r8 12.3
    IL_000a: stloc.0
    IL_000b: ldloc.0
    IL_000c: call int32 [System.Private.CoreLib]System.Convert::ToInt32(float64)
    IL_0011: stloc.1
    IL_0012: ret
Frighten answered 16/2, 2022 at 19:19 Comment(0)
A
0

int myInt = (int)Math.Ceiling(myDouble);

Ashia answered 19/4, 2017 at 23:21 Comment(0)
G
0

Use the inbuilt Convert class. It offers all type of conversion methods whether from int to double, double to float or byte etc.

int i= Convert.ToInt32(500*3.142456778)
Gigot answered 30/1, 2023 at 17:33 Comment(0)
P
-1

I think the best way is Convert.ToInt32.

Prophecy answered 15/11, 2010 at 7:24 Comment(0)
L
-1
label8.Text = "" + years.ToString("00") + " years";

when you want to send it to a label, or something, and you don't want any fractional component, this is the best way

label8.Text = "" + years.ToString("00.00") + " years";

if you want with only 2, and it's always like that

Luzluzader answered 14/7, 2014 at 18:59 Comment(1)
This is most certainly not the best way and you should probably retract your answer. By using ToString you're newing up a lot of other costly resources behind the scenes, like a string formatter and parser which are meant for special purposes. Learn from the answers given here. The closest to best way is to cast to int and truncate the fractional part or use something like Math.Round to get to the closest int you're looking for.Petrosal

© 2022 - 2024 — McMap. All rights reserved.