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. ThinkPHP 多数据库自动连接设计

    配置文件 database.php <?php return array( 'dbname1'=>'mysql://root:root@localhost/dbname1#utf8', ' ...

  2. javascript中的this总结

    1.关于this 我们需要根据 "调用位置" 上函数的 "调用方式" 来确定函数中this使用的 "绑定规则" 2.绑定规则 非严格模式下: ...

  3. Protocol Buffers 在前端项目中的使用

    前言: 公司后端使用的是go语言,想尝试用pb和前端进行交互,于是便有了这一次尝试,共计花了一星期时间,网上能查到的文档几乎都看了一遍,但大多都是教在node环境下如何使用,普通的js环境下很多讲述的 ...

  4. CRT【p3868】[TJOI2009]猜数字

    Description 现有两组数字,每组k个,第一组中的数字分别为:a1,a2,...,ak表示,第二组中的数字分别用b1,b2,...,bk表示.其中第二组中的数字是两两互素的.求最小的非负整数n ...

  5. Bzoj3837 [Pa2013]Filary(随机化)

    题面 权限题 题解 这题有一个很好的性质,就是一定有$k>\frac n2$.接着考虑怎么做. 我们随机选取一个数$x$,然后将所有数与它作差,那么只需要找出$k$个差值使得他们的最大公因数大于 ...

  6. 2017腾讯OMG实习生面试总结

    2017腾讯OMG实习生面试总结 一面 一面有两个面试官,轮着来的,一共是一个半小时,中间等了10分钟左右.结合简历问了问项目,也考察了基础,手写了两道简单的算法题.问题包括: 第一个面试官 1.自我 ...

  7. 【BZOJ 3881】【COCI 2015】Divljak

    http://www.lydsy.com/JudgeOnline/problem.php?id=3881 好难的一道题啊qwq 一开始我想对T建AC自动机,根本不可做. 正解是对S建AC自动机. fa ...

  8. 【贪心+优先队列】POJ3190-Stall Reservations

    [题目大意] 给出每个奶牛挤奶的时间,同一时间同一畜栏内不会有两头奶牛挤奶,问至少要多少个畜栏. [思路] 将奶牛按照挤奶开始的时间进行升序排序,再用一个小顶堆维护每一个畜栏当前的挤奶结束时间.对于当 ...

  9. 【BFS】POJ3669-Meteor Shower

    [思路] 预处理时先将陨石落到各点的最短时间纪录到数组中,然后在时间允许的范围内进行广搜.一旦到某点永远不会砸到,退出广搜. #include<iostream> #include< ...

  10. 大内密探HMM(转)

    源地址:http://blog.csdn.net/ppn029012/article/details/8923501 1. 赌场风云(背景介绍) 最近一个赌场的老板发现生意不畅,于是派出手下去赌场张望 ...