Haskell中floor
和truncate
之间的功能是否存在差异?
它们似乎执行相同的功能,并且它们具有相同的类型签名:
truncate :: (Integral b, RealFrac a) => a -> b
floor :: (Integral b, RealFrac a) => a -> b
答案 0 :(得分:19)
是的,对于负数。如果我们阅读文档,我们会看到:
<强>
truncate :: Integral b => a -> b
强>之间最接近
truncate x
返回0到x
x
的整数
和
<强>
floor :: Integral b => a -> b
强>的最大整数
floor x
返回不大于x
因此,如果我们输入负数,例如-3.5
,我们就会获得:
Prelude> truncate (-3.5)
-3
Prelude> floor (-3.5)
-4
答案 1 :(得分:7)
这不是特定于haskell,但这些功能之间存在差异。 Floor表示不高于给定数字的最高整数。截断意味着在某种程度上移除,在这种情况下是小数部分。那些对零和正数具有相同的效果,但不是负数。
这是Python中的快速比较:
>>> for i in range(-5,6):
... j=0.5*i
... print(j,floor(j),ceil(j),trunc(j),round(j))
...
-2.5 -3 -2 -2 -2
-2.0 -2 -2 -2 -2
-1.5 -2 -1 -1 -2
-1.0 -1 -1 -1 -1
-0.5 -1 0 0 0
0.0 0 0 0 0
0.5 0 1 0 0
1.0 1 1 1 1
1.5 1 2 1 2
2.0 2 2 2 2
2.5 2 3 2 2
本质上,trunc()向零和floor()向负无穷大方向前进。
答案 2 :(得分:4)
查看源代码,差异很快就出现了:
truncate x = m where (m,_) = properFraction x
和
floor x = if r < 0 then n - 1 else n
where (n,r) = properFraction x
我们看到差异只会出现在负数上,所以:
Prelude> floor (negate 2.1)
-3
Prelude> truncate (negate 2.1)
-2
答案 3 :(得分:1)
截断:
1 --> 1
3.1 --> 3
3.9 --> 3
-2.1 --> -2
-2.9 --> -2
楼层:
1 --> 1
3.1 --> 3
3.9 --> 3
-2.1 --> -2
-2.9 --> -3 (Different!...)