2009-01-04 127 views
7

有人能解释为什么int (0.4 * 10.0)4int ((2.4 - 2.0) * 10.0)3在F#中将float转换为int#

然后请解释如何获得4。即我真的必须做int (System.Math.Round((2.4 - 2.0) * 10.0))

对于那些应该如此简单的事情来说,这太丑陋了。

+2

应当指出的是,这不是F#具体的“问题”,而是在大多数语言的性质,在至少所有的.NET。 – 2013-02-07 08:50:22

回答

11

2.4 - 2.0的双重表示是0.399999999999。当您将数字转换为int时,小数部分被截断,因此3.999999999被截断为3.

+1

这是正确的,如果你想得到4.0,那么你可以使用Math.Round: Math.Round((2.4 - 2.0)* 10.0) – Robert 2009-01-04 16:47:53

1

浮点数不是无限精度。一些数字可以完美地表示(任何涉及两个幂的事物,例如1,1/2 = 0.5,1/4 = 0.25等),而其他数字不能(例如1/3不能精确地分解为有限序列两个权力)。通常情况下,斩断无限序列的末尾会导致数字的编码版本稍微小于其真实值。

与事实结合这使(INT)运算符截断,而不是发了,你可以运行到其中一个操作,即应该产生4.0结果3.999999999991代替,成为3

任何时间的情况下你正在尝试将浮动/双精度转换为整数,你要仔细考虑要使用哪个运算符 - 截断(舍入),舍入或舍入到最近。

由于这是浮点表示法的问题,不仅在F#中,而且在C#和(IIRC)Java和其他语言中都是如此。

5

然后还请解释如何得到4.即我真的要做

INT(System.Math.Round((2.4 - 2.0)* 10.0))

它只是如此丑陋的东西应该如此简单。

当然不是,只是定义

let round x = int System.Math.Round(x) 
4

其实,在.net中有一个decimal数据类型,这将有助于你解决这个问题,如果你的号码,可以完全按照小数表示。

2.4m - 2.0m == 0.4m 
2.4 - 2.0 != 0.4 
2

隐蔽一个float数量的int使用:

let i = Convert.ToInt32(f)

+0

只需要注意新用户(如我):需要先打开System – sebhofer 2018-02-06 14:06:37