如何在C#中将小数转换为int?


227

如何将小数转换为整数?


11
知道您是想四舍五入到最接近的int还是只舍去小数点后的数字(即:总是四舍五入)将很有帮助
Dinah

128
老实说,我认为降低真正问题的意义。是的,答案可以在google上找到,但是如果人们停止关闭每一个第二个问题,这是否只会提高网站的质量?它不是像这个问题是垃圾邮件之类的东西,我相信它对许多新手来说都是有用的C#
jay_t55

Answers:


268

使用Convert.ToInt32mscorlib作为

decimal value = 3.14m;
int n = Convert.ToInt32(value);

参见MSDN。您也可以使用Decimal.ToInt32。同样,请参见MSDN。最后,您可以像

decimal value = 3.14m;
int n = (int) value;

使用显式强制转换运算符。参见MSDN


10
请注意:对于某些转换(null0vs ""),转换具有某些令人惊讶的行为。我建议不要使用Convert,除非您绝对需要它的灵活性(例如,在动态键入的情况下)
Eamon Nerbonne 2012年

1
-1,因为这不会在一个价值观,如decimal.MaxValue和decimal.MinValue和结果的工作OverflowException。我相信@Will在这里可以提供更好的答案stackoverflow.com/a/501165/39532
mezoid 2014年

8
要小心,因为Convert.ToInt32Decimal.ToInt32行为会有所不同。从MSDN:Decimal.ToInt32-返回值是十进制值的整数部分;小数位数被截断Convert.ToInt32-返回值舍入到最接近的32位有符号整数。如果值位于两个整数之间,则返回偶数;否则,返回偶数。即,4.5转换为4,和5.5被转换为6
vezucci

67

你不能

好吧,当然可以,但是int(System.Int32)不足以容纳每个可能的十进制值。

这意味着,如果您强制转换大于int.MaxValue的小数,则将溢出,而如果小数小于int.MinValue,则将下溢。

当您下溢/上溢时会发生什么?两件事之一。如果您的构建未经检查(即CLR不在乎),则在值上溢/下溢后,您的应用程序将继续运行,但是int中的值将不是您所期望的。这可能会导致间歇性错误,并且可能难以修复。您最终会将应用程序置于未知状态,这可能导致您的应用程序破坏其正在处理的所有重要数据。不好。

如果检查了程序集(属性-> build->高级->检查算术上溢/下溢或/ checked编译器选项),则当发生下溢/上溢时,您的代码将引发异常。这可能总比没有好。但是,程序集的默认设置是不检查上溢/下溢。

真正的问题是“您想做什么?” 在不知道您的要求的情况下,除了显而易见的事情:没有人可以告诉您在这种情况下该做什么。

如果您根本不在乎,这里的答案是有效的。但是,您应该通过将您的强制转换代码包装在未经检查的代码块中来传达您的理解,即可能会发生溢出,并且没有关系

unchecked
{
  // do your conversions that may underflow/overflow here
}

这样,后面的人就会知道您不在乎,如果将来有人将您的版本更改为/ checked,您的代码也不会意外中断。

如果您只想删除数字的小数部分,而保留整数部分,则可以使用Math.Truncate。

decimal actual = 10.5M;
decimal expected = 10M;
Assert.AreEqual(expected, Math.Truncate(actual));

3
尽管我怀疑如果输入是十进制,它们在幕后是同一回事,但我使用Decimal.Truncate比使用Math.Truncate感到更自在,因为后者也接受双精度,因此可以理解为能够截断偶数不是以10为底的数字,与Decimal.Truncate相反,后者是10以底的数字的真实截断。
布赖恩

7
未检查的上下文不适用于小数;无论如何,对小数进行的操作都将引发OverflowExceptions。
戴夫

46
int i = (int)d;

将给您四舍五入的数字。

如果您想四舍五入到最接近的偶数(即> .5将四舍五入),可以使用

int i = (int)Math.Round(d, MidpointRounding.ToEven);

通常,您可以在C#中的所有数值类型之间进行转换。如果在投射过程中没有丢失的信息,则可以隐式地进行操作:

int i = 10;
decimal d = i;

尽管您仍然可以根据需要明确地执行此操作:

int i = 10;
decimal d = (decimal)i;

但是,如果您要通过演员表丢失信息,则必须明确地进行操作(以表明您知道自己可能会丢失信息):

decimal d = 10.5M;
int i = (int)d;

在这里,您将丢失“ .5”。这样做可能很好,但是您必须对此明确,并进行明确的强制转换以表明您知道自己可能会丢失信息。


1
实际上,你想MidpointRounding.AwayFromZero如果你想> * 0.5〜总是围捕根据我的经验,试图在上面的示例输出在这里寻找的代码了:msdn.microsoft.com/en-us/library/...
利亚洛夫格伦

@ElijahLofgren有点取决于:如果要进行统计,ToEven则应防止统计偏差。但是,如果您使用可收费的物品或金钱来操作,AwayFromZero似乎是正确的选择。
mbx

22
decimal d = 2;
int i = (int) d;

这应该很好。


小心,带有明确的转换信息可能会丢失。
Phaedrus,

21
从十进制转换为int时,信息几乎总是会丢失,但是我认为这很重要。
Dinah


8

System.Decimal实现IConvertable具有ToInt32()成员的接口。

打电话System.Decimal.ToInt32()给您有用吗?


2
文档中:“此API支持.NET Framework基础结构,不能直接在您的代码中使用”。为什么不使用Convert.ToInt32?
H.Wolper

7

快速舍入的一个好窍门是在将小数转换为整数之前加0.5。

decimal d = 10.1m;
d += .5m;
int i = (int)d;

仍然离开i=10,但是

decimal d = 10.5m;
d += .5m;
int i = (int)d;

这样会四舍五入i=11


5
当有Math.Floor和Math.Ceiling时,为什么还要这么做呢?
巴达罗

当时,我对C#还是比较陌生,由于某种原因,我没有意识到这些功能的存在。这实际上是我从C / C ++中学到的一个技巧,它显然更有用。
DeadlyBrad42

1
如果十进制值为-9.3怎么办?
超级猫



6

将小数点四舍五入到最接近的整数

decimal a ;
int b = (int)(a + 0.5m);

a = 49.9,则b = 50

a = 49.5,则b = 50

a = 49.4,则b = 49


0

我发现,如果您使用装箱的十进制(即对象类型内的十进制值),则强制转换运算符不起作用。在这种情况下,Convert.ToInt32(十进制作为对象)可以正常工作。

从数据库中检索IDENTITY / AUTONUMBER值时会出现这种情况:

SqlCommand foo = new SqlCommand("INSERT INTO...; SELECT SCOPE_IDENTITY()", conn);
int ID = Convert.ToInt32(foo.ExecuteScalar());  // works
int ID = (int)foo.ExecuteScalar();              // throws InvalidCastException

请参阅4.3.2取消装箱转换


2
向其中添加更多内容以供参考:这是因为您只能将其拆箱为相同的原始类型。此处SELECT SCOPE_IDENTITY()返回numeric(38, 0)翻译成decimal.NET的内容。foo.ExecuteScalar()返回一个decimal盒装作为object其不能直接浇铸到int(int)(decimal)foo.ExecuteScalar()Convert.ToInt32(foo.ExecuteScalar())会工作。
rageit 2014年

0

似乎没有答案可以解决OverflowException / UnderflowException,该异常来自尝试转换int范围之外的小数。

int intValue = (int)Math.Max(int.MinValue, Math.Min(int.MaxValue, decimalValue));

如果十进制值超出int范围,则此解决方案将返回可能的最大或最小int值。当值在int范围内时,您可能需要使用Math.Round,Math.Ceiling或Math.Floor添加一些舍入。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.