问题
Does there exist a difference in functionality between floor
and truncate
in Haskell?
They seem to perform the same functionality and they have the same type signature:
truncate :: (Integral b, RealFrac a) => a -> b
floor :: (Integral b, RealFrac a) => a -> b
回答1:
Yes, for negative numbers. If we read the documentation, we see:
truncate :: Integral b => a -> b
truncate x
returns the integer nearestx
between zero andx
and:
floor :: Integral b => a -> b
floor x
returns the greatest integer not greater thanx
So if we enter a negative number, like -3.5
we obtain:
Prelude> truncate (-3.5)
-3
Prelude> floor (-3.5)
-4
回答2:
It's not haskell specific, but there's a difference between those functions. Floor means the highest integer no higher than a given number. Truncate means to remove at some length, in this case the fractional part. Those have the same effect for zero and positive numbers, but not negative.
Here's a quick comparison in 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
Essentially trunc() goes towards zero and floor() towards negative infinity.
回答3:
Looking at the source code the difference emerges quite quickly:
truncate x = m where (m,_) = properFraction x
and
floor x = if r < 0 then n - 1 else n
where (n,r) = properFraction x
we see the difference will only emerge on negative numbers and so:
Prelude> floor (negate 2.1)
-3
Prelude> truncate (negate 2.1)
-2
回答4:
Truncate:
1 --> 1
3.1 --> 3
3.9 --> 3
-2.1 --> -2
-2.9 --> -2
Floor:
1 --> 1
3.1 --> 3
3.9 --> 3
-2.1 --> -2
-2.9 --> -3 (Different!...)
来源:https://stackoverflow.com/questions/45811770/is-there-a-difference-between-floor-and-truncate-in-haskell