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)。 这是一个错误吗?
答案 0 :(得分:8)
不,这是记录在案的行为。 Convert.ToInt32(double)
向上或向下舍入一个数字,中间点向下舍入到偶数:
返回值
value
,四舍五入到最近的32位有符号整数。如果value
介于两者之间 整数,偶数返回;也就是说,4.5转换为4,而5.5是 转换为6。
从C#3规范的第6.2.1节开始,施法始终向零舍入(例如1.8轮到1) -
...
否则,源操作数为 四舍五入到最近 积分值。如果是这个积分值 在目的地范围内 然后输入这个值就是结果 转换。
请注意,这不仅仅是关于银行家的四舍五入:它是关于一般的舍入:(int)0.9
和Convert.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.