查看Convert.ToInt32()
它的 msdn 文档指出:
如果 value 在两个整数的中间,则返回偶数;即4.5转换为4,5.5转换为6。
http://msdn.microsoft.com/en-us/library/ffdk7eyz.aspx
为什么是这样?
当然,四舍五入到最接近的整数会更合乎逻辑,不是吗?如果是这样的话,4.5 会变成 5,5.5 会变成 6,这似乎更直观。
查看Convert.ToInt32()
它的 msdn 文档指出:
如果 value 在两个整数的中间,则返回偶数;即4.5转换为4,5.5转换为6。
http://msdn.microsoft.com/en-us/library/ffdk7eyz.aspx
为什么是这样?
当然,四舍五入到最接近的整数会更合乎逻辑,不是吗?如果是这样的话,4.5 会变成 5,5.5 会变成 6,这似乎更直观。
Rounding的维基百科条目的历史部分有一些关于“四舍五入”在计算中的作用的陈述。有趣的是,似乎“银行家四舍五入”几乎没有证据表明它在任何意义上都是官方的,因此只能被称为俚语。
如果您订阅该舍入机制,它只会“更合乎逻辑”。银行家四舍五入(在这种情况下是默认设置)也是完全合乎逻辑的。
想象一下,如果银行将每一小部分金额四舍五入到最接近的一美分,那么他们每天处理的数以百万计的交易将减少(损失很多,对于愤世嫉俗的人)的钱。好的,所以这个例子是愤世嫉俗的。
走向最接近的偶数(或奇数,但历史另有选择)意味着并非每个舍入分辨率都会上升,现在有些可能会下降。当您将此应用于平均定律时,在考虑谁负责支付额外的半便士时,它成为一个公平的解决方案。
至于为什么选择它作为框架,这个问题试图解决它:
当然,这一切都可以追溯到金融时代,它对整数的适用性可能会受到质疑,但何必呢?接受它,如果你愿意,可以覆盖它,只要了解它是如何工作的。
如果您向您提供非整数,Convert.ToInt32
则实际上首先需要执行类似的操作Convert.ToDouble
,然后Math.Round
使用重载来更改舍入逻辑。
这正是将MidpontRounding
重载添加到Math.Round
.
因此,为了正确舍入,您应该使用 Math.Round 而不是 Convert.ToInt32。
不考虑 MidpointRounding.ToEven(银行家的舍入)或 MidpointRounding.AwayFromZero 是否是更好的默认值这一主观问题。
在设计这个时,微软会考虑 .NET 旨在取代的语言。
VB 经典一直默认使用银行家四舍五入法。
C / C++ 转换在强制转换时会截断,并且在运行时库中有库函数 floor() 和 ceil() - 但是(AFAIK,可能是错误的)没有轮函数。
Java 有一个 Math.round,在文档中被描述为等同于 Math.round(a+0.5)。这可能不是大多数人对负数的期望(-3.5 轮到 -3)。
与来自 C/C++ 或 Java 的开发人员相比,VB 开发人员可能需要更多的支持。
因此,在设计 .NET 时,类库将提供和方法Floor
,并且 Round 行为默认为 VB 的行为似乎是合理的。Ceiling
Round
Convert.ToInt32() 使用 Round 方法似乎也是合理的(尽管我想可以为 Floor 制作一个案例,以与铸造保持一致)。
如果您想要这种行为,您需要使用Math.Round
并指定MidpointRounding.AwayFromZero
.
例如:
int result = (int)Math.Round(4.5, MidpointRounding.AwayFromZero);
演示:http: //ideone.com/ZAbBL
Convert.ToInt32(double)
不使用Math.Round
自身,而是以这种方式实现(ILSpy):
public static int ToInt32(double value)
{
if (value >= 0.0)
{
if (value < 2147483647.5)
{
int num = (int)value;
double num2 = value - (double)num;
if (num2 > 0.5 || (num2 == 0.5 && (num & 1) != 0))
{
num++;
}
return num;
}
}
else
{
if (value >= -2147483648.5)
{
int num3 = (int)value;
double num4 = value - (double)num3;
if (num4 < -0.5 || (num4 == -0.5 && (num3 & 1) != 0))
{
num3--;
}
return num3;
}
}
throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
}