Converter -> public static int ToInt32(double value) 你用对了么?

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

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

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

7.5: 8
6.5: 6

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

 1 [__DynamicallyInvokable]
 2 public static int ToInt32(double value)
 3 {
 4     if (value >= 0.0)
 5     {
 6         if (value < 2147483647.5)
 7         {
 8             int num = (int) value;
 9             double num2 = value - num;
10             if ((num2 > 0.5) || ((num2 == 0.5) && ((num & 1) != 0)))
11             {
12                 num++;
13             }
14             return num;
15         }
16     }
17     else if (value >= -2147483648.5)
18     {
19         int num3 = (int) value;
20         double num4 = value - num3;
21         if ((num4 < -0.5) || ((num4 == -0.5) && ((num3 & 1) != 0)))
22         {
23             num3--;
24         }
25         return num3;
26     }
27     throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
28 }
29
30
31
32
33  1 0x1[__DynamicallyInvokable]
34 public static int ToInt32(double value)
35 {
36     if (value >= 0.0)
37     {
38         if (value < 2147483647.5)
39         {
40             int num = (int) value;
41             double num2 = value - num;
42             if ((num2 > 0.5) || ((num2 == 0.5) && ((num & 1) != 0)))
43             {
44                 num++;
45             }
46             return num;
47         }
48     }
49     else if (value >= -2147483648.5)
50     {
51         int num3 = (int) value;
52         double num4 = value - num3;
53         if ((num4 < -0.5) || ((num4 == -0.5) && ((num3 & 1) != 0)))
54         {
55             num3--;
56         }
57         return num3;
58     }
59     throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
60 }
61
62  

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) 你用对了么?

时间: 2024-10-12 15:34:55

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

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

1 package math; 2 3 public class TestMath_round { 4 public static void main(String[] args) { 5 System.out.println(Math.round(0.5));//1 6 System.out.println(Math.round(-0.5));//0 7 System.out.println(Math.round(-0.501));//-1 8 //Math类的四舍五入方法round进行负数操

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

学了数组之后,感觉有好多操作需要经常去写,很不方便,因此自己做了一个工具类,方便调用,方法可能不全,希望大家可以添加,让我使用也方便一点儿. 1 public class ArrayUtils { 2 //求数组的最大值(int) 3 public static int getMax(int[] arr){ 4 int max = arr[0]; 5 for(int i = 0;i<arr.length;i++){ 6 if(max<arr[i]){ 7 max = arr[i]; 8 } 9

C++ static变量出现 无法解析的外部符号:public: static 的问题

转自:http://bbs.csdn.net/topics/390183594 在头文件中定以后,应在类的生命之外,重新定义一次. 1 class A 2 { 3 public: 4 void print() 5 { 6 cout<<"a = "<<a<<'\n'<<"b = "<<b<<endl; 7 cout<<"str = "<<str<&

hadoop 关于java中的public static 变量是不能被改变的?

我在写hadoop的时候,在mapper里定义了一个public static int rownums = 0.但我在main里对这个变量进行了赋值. 结果在循环的过程中,根本没有任何输出,因为我是用这个变量来控制循环的,所以我猜想可能是不能改变这个值,于是我直接在初始定义的时候直接赋上正确的值,所以这样最后程序就正确运行了. 但是我又新建了一个工程写了一个小程序,试了一下,明明是能够改变,正确输出的. 不能理解了. hadoop 关于java中的public static 变量是不能被改变的?

String转换char数组和int型和Double型

package z; public class z { public static void main(String[] args) { String s = "123"; char[] c = s.toCharArray();// String转换为char[] for (int i = 0; i < c.length; i++) { System.out.println(c[i]); } int s_ = Integer.parseInt(s);// String转换为int

JAVA:从public static void main(String args[])開始

我们都知道当你要执行一个JAVA文件的时候必需要有一个main函数. 这是为什么呢? 跟C语言的道理一样,当你执行一个文件的时候.你必需要有一个入口函数或者入口地址,在C里面是main函数.相同的在JAVA里面则是public static void main(String args[])这样一个入口函数.这是java程序的入口地址,java虚拟机执行程序的时候首先找的就是main方法.跟C语言里面的main()函数的作用是一样的.仅仅有有main()方法的java程序才可以被java虚拟机欲行

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

主函数的一般写法如下: public static void main(String[] args){-} 下面分别解释这些关键字的作用: (1)public关键字,这个好理解,声明主函数为public就是告诉其他的类可以访问这个函数. (2)static关键字,告知编译器main函数是一个静态函数.也就是说main函数中的代码是存储在静态存储区的,即当定义了类以后这段代码就 已经存在了.如果main()方法没有使用static修饰符,那么编译不会出错,但是如果你试图执行该程序将会报错,提示ma

使用log4cplus时遇到的链接错误:无法解析的外部符号 &quot;public: static class log4cplus::Logger __cdecl log4cplus::Logger::getInstance(class std::basic_string&lt;wchar_t,struct std::char_traits&lt;wchar_t&gt;,

#include "stdafx.h" #include <log4cplus/logger.h> #include <log4cplus/loggingmacros.h> #include <log4cplus/configurator.h> #include <log4cplus/fileappender.h> #include <log4cplus/win32debugappender.h> #include <l

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

public staticvoid main(String[] args)为Java程序的入口方法,JVM在运行程序的时候,会首先查找main方法.其中,public是权限修饰符,表明任何类或对象都可以访问这个方法,static表明main方法是一个静态方法,即方法中的代码是存储在静态存储区的,只要类被加载后,就可以使用该方法而不需要通过实例化对象来访问,可以直接通过类名.main()直接访问,JVM在启动的时候就是按照上述方法的签名(必须有public与static修饰,返回值为void,且方