C#错误从double转换为int32

时间:2010-06-01 13:28:01

标签: c#

using NUF = NUnit.Framework;
[NUF.Test]public void DifferentCastingTest() {
     NUF.Assert.That((int)0.499999D, NUF.Is.EqualTo(0)); 
     NUF.Assert.That((int)0.500000D, NUF.Is.EqualTo(0)); // !!! row 1
     NUF.Assert.That((int)1.499999D, NUF.Is.EqualTo(1)); 
     NUF.Assert.That((int)1.500000D, NUF.Is.EqualTo(1)); // !!! row 2

     NUF.Assert.That(System.Convert.ToInt32(0.499999D), NUF.Is.EqualTo(0)); 
     NUF.Assert.That(System.Convert.ToInt32(0.500000D), NUF.Is.EqualTo(0)); // !!! 
     NUF.Assert.That(System.Convert.ToInt32(1.499999D), NUF.Is.EqualTo(1)); 
     NUF.Assert.That(System.Convert.ToInt32(1.500000D), NUF.Is.EqualTo(2)); //!!! row 3
  }

通过转换和Convert.ToInt32(参见第2行和第3行)以不同方式转换相同的double值(1.5D),并且在不同模式下舍入两个具有相同尾数(0.5和1.5)的double(参见第1行)和2)。 这是一个错误吗?

4 个答案:

答案 0 :(得分:8)

不,这是记录在案的行为。 Convert.ToInt32(double)向上或向下舍入一个数字,中间点向下舍入到偶数:

  

返回值

     

value,四舍五入到最近的32位有符号整数。如果value介于两者之间   整数,偶数返回;也就是说,4.5转换为4,而5.5是   转换为6。

从C#3规范的第6.2.1节开始,施法始终向零舍入(例如1.8轮到1) -

  

...

     

否则,源操作数为   四舍五入到最近   积分值。如果是这个积分值   在目的地范围内   然后输入这个值就是结果   转换。

请注意,这不仅仅是关于银行家的四舍五入:它是关于一般的舍入:(int)0.9Convert.ToInt32(0.9)之间存在差异。

答案 1 :(得分:2)

不,这不是一个错误。 .Net uses banker's rounding by default。 如果这不是理想的行为,您可以指定舍入方法。

答案 2 :(得分:2)

Casting总是截断数字而不是舍入它。

例如,int new = (int)1.999999D;会为您提供一个名为new的int,其值为1

Convert.ToInt32表示会返回此信息:

  

值,四舍五入到最接近的32位   有符号整数。如果价值是中途   在两个整数之间,偶数   号码被退回;也就是说,4.5是   转换为4,转换为5.5   到6。

答案 3 :(得分:0)

这完全符合语言规范和MSDN文档。

通过设计转换为整数返回浮点数的整数部分,并将Convert.ToInt32的返回值四舍五入为最接近的32位有符号整数。如果值在两个整数之间,则返回偶数;也就是说,4.5转换为4,5.5转换为6.