【问题标题】:Integer to float整数浮动
【发布时间】:2010-10-19 12:24:46
【问题描述】:

此代码有效:

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

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

【问题讨论】:

标签: haskell floating-point integer


【解决方案1】:

如果你想执行小数除法,你可以使用fromIntegral从任何Integral类型转换,或者fromInteger专门从Integer转换。

还有与其他数值类型类相关的类似函数:toRationalfromRationalrealToFrac 等。当然,您可以使用 roundfloor、@ 将小数类型转换回整数类型987654330@之类的。

最后,如果你真的想要 integer 除法,而不是小数除法和四舍五入,还有 divquot 函数(取决于你想要什么截断行为)。

另外,您可能应该将您的函数编写为posToXY a b = round $ a / b 之类的东西。不必要的do 和多行使其更难阅读。

【讨论】:

  • posToXY a b = round $ a / b - 在这种情况下,我个人更喜欢括号以提高可读性 - 它不必考虑(即使只是一瞬间)运算符优先级,它看起来更像是数学表达式它代表。
  • @mokus:是的,我同意。出于习惯,我在这里只使用了($),我可能会在实际代码中使用括号。
  • @C.A.McCann you probably should write your function as... -- 您是否建议更好地将这两个函数合并为一个?
【解决方案2】:

您可以使用fromIntegral 将任何 Integral 类型转换为任何 Num 类型。所以:

let y = fromIntegral a / fromIntegral b

【讨论】:

    【解决方案3】:

    您的代码可以很容易地简化为

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

    然后

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

    【讨论】:

      【解决方案4】:

      如果要整数除法,可以使用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)
      

      【讨论】:

        猜你喜欢
        • 2016-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-04
        • 1970-01-01
        相关资源
        最近更新 更多