开发者

C# error casting from double to int32

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
  }

The same double value (1.5D) is converted in different way by casting and Convert.ToInt32 (see row 2 and 3), and two double with same mantissa (0.5 and 1.5) is rounded in different mode (see row 1 and 2). Is it a bug?


Nope, it's documented behaviour. Convert.ToInt32(double) rounds a number up or down, with half-way points rounding to even:

Return Value

value, rounded to the nearest 32-bit signed integer. If value is halfway between two whole numbers, the even number is returned; that is, 4.5 is converted to 4, and 5.5 is converted to 6.

Casting always rounds towards zero (so 1.8 rounds to one, for example) - from section 6.2.1 of the C# 3 spec:

...

Otherwise, the source operand is rounded towards zero to the nearest integral value. If this integral value is within the range of the destination type then this value is the result of the conversion.

Note that this isn't just about bankers' rounding: it's about rounding in general: there's a difference between (int)0.9 and Convert.ToInt32(0.9).


No, it is not a bug. .Net uses banker's rounding by default. If it's not desirable behavior, you can specify the rounding method.


Casting always truncates the number rather than rounding it.

For example, int new = (int)1.999999D; would give you an int named new with the value 1.

Convert.ToInt32 says it returns this:

value, rounded to the nearest 32-bit signed integer. If value is halfway between two whole numbers, the even number is returned; that is, 4.5 is converted to 4, and 5.5 is converted to 6.


This is exactly according to both the language spec and the MSDN documentation.

Casting to an integer by design returns the integer part of a floating point number, and the return value of Convert.ToInt32 is rounded to the nearest 32-bit signed integer. If value is halfway between two whole numbers, the even number is returned; that is, 4.5 is converted to 4, and 5.5 is converted to 6.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜