Convert.ToInt32()  是我们经常使用的方法,但如果我们写如下的代码,能确定它的输出值么?

  var x = 7.5;
Console.WriteLine(7.5 + ": " + Convert.ToInt32(x));
x = 6.5;
Console.WriteLine(6.5 + ": " + Convert.ToInt32(x));

让我意外的是,它的输出为:

7.5: 8
6.5: 6

有点疑惑,所以用Reflector看下了代码:

 [__DynamicallyInvokable]
public static int ToInt32(double value)
{
if (value >= 0.0)
{
if (value < 2147483647.5)
{
int num = (int) value;
double num2 = value - num;
if ((num2 > 0.5) || ((num2 == 0.5) && ((num & ) != )))
{
num++;
}
return num;
}
}
else if (value >= -2147483648.5)
{
int num3 = (int) value;
double num4 = value - num3;
if ((num4 < -0.5) || ((num4 == -0.5) && ((num3 & ) != )))
{
num3--;
}
return num3;
}
throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
} 0x1[__DynamicallyInvokable]
public static int ToInt32(double value)
{
if (value >= 0.0)
{
if (value < 2147483647.5)
{
int num = (int) value;
double num2 = value - num;
if ((num2 > 0.5) || ((num2 == 0.5) && ((num & ) != )))
{
num++;
}
return num;
}
}
else if (value >= -2147483648.5)
{
int num3 = (int) value;
double num4 = value - num3;
if ((num4 < -0.5) || ((num4 == -0.5) && ((num3 & ) != )))
{
num3--;
}
return num3;
}
throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
}

6-15行的处理说明了问题,((num2 == 0.5) && ((num & 1) != 0) 判断如果是奇数,那么结果自增,否则不处理。Why? 为什么要这么处理? google了一下,发现.net的四舍五入都会使用“银行家四舍五入算法”:

The History section of the Wikipedia entry for Rounding has some statements about the role of "round to even" in computing. Interestingly, it appears "Bankers Rounding" has little evidence to state it was official in any sense of the word, so can only be chalked up as slang terminology.

It is only "more logical" if you subscribe to that rounding mechanism. Bankers rounding (which is the default in this case) is also perfectly logical.

Imagine if banks rounded up to the nearest penny for every fractional amount, they would make a lot less (lose a lot of, for the cynical) money with the millions upon millions of transactions that are processed daily. OK, so this example is cynical.

Going towards the nearest even number (or odd, but history chose otherwise) means that not every rounding resolution goes upsome can now go down. When you put this to the law of averages, it becomes a fair solution to use when considering who is responsible for paying for the extra half penny.

As for why this was chosen for the framework, this question attempts to address it:

Why does .NET use banker's rounding as default?

Of course, this all harks back to financial days and its applicability to integral numbers could be questioned, but why bother? Accept it, override it if you want to, just understand how it works.

请参阅:

http://stackoverflow.com/questions/11431793/convert-toint32-rounds-to-the-nearest-even-number

http://stackoverflow.com/questions/311696/why-does-net-use-bankers-rounding-as-default

Converter -> public static int ToInt32(double value) 你用对了么?的更多相关文章

  1. 【java】java.lang.Math:public static long round(double a)和public static int round(float a)

    package math; public class TestMath_round { public static void main(String[] args) { System.out.prin ...

  2. Java——int、double型数组常用操作工具类

    学了数组之后,感觉有好多操作需要经常去写,很不方便,因此自己做了一个工具类,方便调用,方法可能不全,希望大家可以添加,让我使用也方便一点儿. public class ArrayUtils { //求 ...

  3. 调用类java.lang.Math的成员方法"public static double random"运算下面表达式10000次,统计其中生成的整数0,1,2,.....20的个数分别是多少,并输出统计结果.(int)(Math.random()*20+0.5)

    public class Test2 { public static void main(String args[]){ int num; int count[]=new int[21]; for(i ...

  4. c#的中英文混合字符串截取 public static string SubString(string inputString, int byteLength)

    /// <summary>        /// c#的中英文混合字符串截取(区分中英文)        /// </summary>        /// <param ...

  5. 大话java基础知识一之为什么java的主函数入口必须是public static void

    为什么java的主函数入口必须是public static void main (String[] args); 很多写javaEE好几年的程序员经常会记得java的主函数就是这么写的,但实际上为什么 ...

  6. public static void main(String[] args){}函数诠释

    public static void main(String[] args){}函数诠释 主函数的一般写法如下: public static void main(String[] args){-} 下 ...

  7. 《Java程序员面试笔试宝典》之为什么需要public static void main(String[] args)这个方法

    public staticvoid main(String[] args)为Java程序的入口方法,JVM在运行程序的时候,会首先查找main方法.其中,public是权限修饰符,表明任何类或对象都可 ...

  8. 【java】计算一段代码执行时长java.lang.System类里的public static long currentTimeMillis()方法

    public class Test_currentTimeMillis { public static void main(String[] args) { long start=System.cur ...

  9. 主函数特别之处:public static void main(String[] args)

    public static void main(String[] args) public class Test_java {//主函数特殊之处 public static void main(Str ...

随机推荐

  1. 导出数据到word

    打野的时候,碰到一个需求,导出简历信息. 两条思路: 第一条,直接画所有的表格,填充数据. 第二条,加载一个空的模板,然后填充数据. 因为导出的有格式的,所以最后选择了使用模板进行替换,然后填充数据. ...

  2. String的hashCode分析

    /** * Returns a hash code for this string. The hash code for a * {@code String} object is computed a ...

  3. CentOS7安装和配置vsftpd

    (1)vsftpd基本介绍 作用:实现文件共享 1)vsftpd两种模式 主动模式 所谓主动模式,指的是FTP服务器"主动"去连接客户端的数据端口来传输数据,其过程具体来说就是:客 ...

  4. python 字符串,数学之间的不可描述的关系

    首先说一下输入: >>> a=raw_input(" ") 1.234 >>> a '1.234' >>> 可以看到使用raw ...

  5. Mac下配置PHP支持GD库FreeType

    一句话脚本 curl -s http://php-osx.liip.ch/install.sh | bash -s 5.6 记得要FQ哦. 或者下面代码保存成.sh ,代码从http://php-os ...

  6. BZOJ 2323: [ZJOI2011]细胞

    嗯..csdn发得出markdown了..请移步~ 个人觉得那个帅一点 嗯 好题啊!! 矩乘+DP 蒟蒻的我一开始发现了斐波那契数列之后就不会搞了.. 那个..什么质量相同两种方案相同就是扯淡的..想 ...

  7. [USACO 2017 Jan Gold] Tutorial

    Link: 传送门 A: 按值大小插入后用树状数组统计两边个数 #include <bits/stdc++.h> using namespace std; #define X first ...

  8. [USACO 2018 Jan Gold] Tutorial

    Link: USACO 2018 Jan Gold 传送门 A: 对于不同的$k$,发现限制就是小于$k$的边不能走 那么此时的答案就是由大于等于$k$的边形成的图中$v$所在的连通块除去$v$的大小 ...

  9. BZOJ 3505 [Cqoi2014]数三角形(组合数学)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3505 [题目大意] 给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个. 注 ...

  10. [TCO2013]LitPanels

    题意:一个$n\times m$的无色网格,你可以在其中选择两个$x\times y$的子矩形并在其中将其中任意的格子涂上颜色,问最终能得到多少种不同的网格 做这题会用到一个概念叫包围盒(boundi ...