整数转浮点数

22
这段代码有效:
posToXY :: Float -> Float -> Integer
posToXY a b = do
        let y = a / b
        round y

但这并不起作用:

posToXY :: Integer -> Integer -> Integer
posToXY a b = do
        let y = a / b
        round y

我知道整数类型没有定义'/'操作符,但是我不知道如何修复代码以便使用整数参数。


请参阅https://dev59.com/3XM_5IYBdhLWcg3wZSI6。 - Don Stewart
还有https://dev59.com/dnA75IYBdhLWcg3weY_u - Don Stewart
4个回答

30

如果您想进行小数除法运算,可以使用fromIntegral将任何Integral类型转换,或者使用fromInteger仅从Integer特定类型进行转换。

与其他数字类型类相关的类似函数有:toRationalfromRationalrealToFrac等。当然,您也可以使用roundfloorceiling等函数将小数类型转换回整数类型。

最后,假设您实际上想要的是整数除法,而不是先进行小数除法再进行舍入,那么可以使用divquot函数(具体取决于您想要的截断行为)。

此外,您可能应该将函数编写为像posToXY a b = round $ a / b这样的形式。不必要的do关键字和多行代码使得代码更难阅读。


1
posToXY a b = round $ a / b -- 在这种情况下,我个人更喜欢使用括号以提高可读性 - 这样可以避免考虑运算符优先级(即使只有一瞬间),并且它看起来更像它所代表的数学表达式。 - mokus
@mokus:是的,我同意。我在这里只是出于习惯使用了($),在实际代码中我可能会使用括号。 - C. A. McCann
@C.A.McCann 你最好将函数写成这样... -- 你是建议最好将这两个函数合并成一个吗? - Wolf

8
您可以使用fromIntegral将任何整型转换为任何数字类型。因此,代码如下:
let y = fromIntegral a / fromIntegral b

7

你的代码可以轻松简化为:

posToXY :: Float -> Float -> Integer
posToXY a b = round (a / b)

那么,
posToXY :: Integer -> Integer -> Integer
posToXY a b = round (fromIntegral a / fromIntegral b)

3

如果你想进行整数除法,可以使用 div

posToXY :: Integer -> Integer -> Integer
posToXY = div

请注意,这与对浮点数除法进行四舍五入不完全相同,因为 div 总是向下取整。

如果需要更一般的类型签名,可以使用以下方法

p :: (Real a, Real a1, Integral b) => a -> a1 -> b
posToXY a b = round (realToFrac a / realToFrac b)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接