【问题标题】:Haskell - how can I check if number is Double/Float?Haskell - 如何检查数字是否为 Double/Float?
【发布时间】:2011-02-22 19:34:40
【问题描述】:

我想做这样的事情:

x `mod` 1.0 == 0 // => int

但似乎 mod 仅适用于 int...帮助! 编辑: 我正在尝试检查给定的数字是否为三角形,http://en.wikipedia.org/wiki/Triangle_number 所以我的想法是检查 n1 是否为 Int...

(n*(n+1))/2 = s => n1 = (-1 +sqrt(1 + 8s))/2

【问题讨论】:

  • 嗯?你的意思是检查 Float 是否不是整数?
  • 用浮点数做这种事情通常是个坏主意,因为舍入错误很容易让你绊倒。

标签: haskell floating-point integer


【解决方案1】:

要确定某个FloatDouble 是否与Haskell 中的Integer 无法区分,请同时使用floorceiling。比如:

if floor n == ceiling n
  then "It was some integer."
  else "It's between integers."

您还可以用二进制表示的浮点数做一些花哨的事情,由 RealFloat 类型类公开:

http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#t%3ARealFloat

【讨论】:

  • 你来不及了,我自己找到了解决方案,检查我上面的评论;)
  • 你说“他们自己”的地方我想你的意思是“我自己”。
【解决方案2】:

总编辑:

好的,我仍然不确定您要在这里完成什么。

  • 首先,任何模 1 都将为零,因为模函数仅对整数有意义。如果要取小数类型的模,可以先转换为整数。 编辑:尽管物有所值,Data.Fixed 确实具有用于非整数值的 mod' 函数。
  • 我也不知道您所说的“检查 n1 是否为 Int”是什么意思。要么是,要么不是;您无需在运行时检查。 编辑:好的,我现在看到您只是在检查一个值是否具有小数部分。 Paul Johnson 在上面正确指出,谨慎使用浮点值执行此类操作是明智之举。
  • 如果您想在同一计算中混合使用modsqrt 操作,则必须手动在适当的类型之间进行转换。 fromIntegral 会将任何整数类型转换为任何数字类型,floorceilinground 会将小数类型转换为整数类型。

【讨论】:

  • 请检查我的编辑,我正在尝试检查给定的数字是否是三角形数字
  • 感谢提供线索,现在我做到了(天花板 x == 地板 x),它似乎工作了;)(如果 x 有派系部分,则为 false)
  • @MMM:好吧,我仍然很困惑,但很高兴我能帮上忙……?
  • 为什么会感到困惑?我的问题是:用户给出数字 s,所以我检查 s = n(n + 1)/2,n 是否自然,没有派系部分,如果是,给定“s”是三角形数......我是对的?:)
  • @camccann:关于“模函数只对整数有意义”:reference.wolfram.com/mathematica/ref/PolynomialRemainder.html,在 Python 中,您可以使用像 7.2 % 5 这样的模数,它可能对计算您需要给出的更改很有用硬币等。
【解决方案3】:

检查一个数字是否为三角形的更好方法是生成一个三角形数字列表,然后查看您的候选人是否在其中。由于这是一个学习问题,我将给出提示而不是答案。

使用列表推导生成三角数。

由于它们会按顺序排列,因此您可以查看是否经过它们。

如果您正在处理大数字,另一种方法是使用二分搜索来缩小可能导致您的候选人的行数。

【讨论】:

  • 但是这个列表会是无穷大吗?当数字大于搜索时,Haskell 停止搜索自己?
  • 是的,列表将是无限的。不,除非你告诉它,否则 Haskell 不会意识到这一点。所以你需要弄清楚如何让搜索终止。
  • 哪种方法更好?它肯定比只使用公式更昂贵。它也几乎可以肯定是更多的代码。
  • 浮点数可能很棘手,尤其是在比较它们时。很容易得到 3.999999982 而不是 4.0,此时您的算法将失败。即使它似乎大部分时间都有效,但你永远不知道下一个案例是否会失败。因此,如果您正在处理整数,那么最好找到一种方法来处理整数。
猜你喜欢
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 2016-03-29
  • 2011-05-31
相关资源
最近更新 更多