将 double 转换为 int

什么是最好的方法来转换一个 double到一个 int? 是否应该使用强制转换?

423078 次浏览

是啊,为什么不呢?

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

使用 Convert类也很有效。

int someOtherInt = Convert.ToInt32(someDouble);

如果需要默认的向零截断行为,可以使用强制转换。或者,您可能想使用 Math.CeilingMath.RoundMath.Floor等-虽然您仍然需要一个强制转换后。

不要忘记,int的范围比 double的范围小得多。如果值在未检查的上下文中超出了 int的范围,那么从 doubleint的强制转换不会引发异常,而对 Convert.ToInt32(double)的调用会引发异常。如果值超出范围,则转换的结果(在未检查的上下文中)显式未定义。

Convert.ToInt32是转换的最佳方式

如果您使用强制转换,也就是说,(int)SomeDouble,您将截断小数部分。也就是说,如果 SomeDouble是4.9999,结果将是4,而不是5。转换为 int 不会四舍五入。如果你想四舍五入使用 Math.Round

我的方法是:

 - Convert.ToInt32(double_value)
- (int)double_value
- Int32.Parse(double_value.ToString());

我认为最好的办法是 Convert.ToInt32

这里有一个完整的例子

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);
}
}

如果你想把数字四舍五入到更接近的整数,可以这样做:

i = (int) Math.Round(x / y); // Line replaced

最好的方法是简单地使用 Convert.ToInt32。它是快速的,也正确地轮流。

为什么要把事情弄得更复杂?

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

当你想把它发送到一个标签,或者别的什么东西,你不想要任何小数组件,这是最好的方法

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

如果你只想要两个,而且总是这样

数学天花板(myDouble) ;

没有一个代码样本表现出一个学生所期望的正常行为(半数被四舍五入)。大多数人会想到的是:

double d = 1.5;
int i = (int)Math.Round(d, MidpointRounding.AwayFromZero);

没有比这更好的了。这真的取决于你想要什么,性能,准确性,等等。

但看到不同 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

关于 IL 之间没有很大的区别 (int)Convert.ToInt32

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

结果 :

    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)理论上,指令越少,速度越快,但我怀疑没有人能测量出来。

还有

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

结果 :

    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