为了账号安全,请及时绑定邮箱和手机立即绑定

Haskell范围和浮动

Haskell范围和浮动

为什么浮点数的Haskell范围符号的行为与整数和字符的行为不同?Prelude> [1, 3 .. 10] :: [Int][1,3,5,7,9] Prelude> [1, 3 .. 10] :: [Float][1.0,3.0,5.0,7.0,9.0,11.0]Prelude> ['a', 'c' .. 'f']"ace"如果最后一个元素接近上限,我会理解它,但这显然不是一个舍入问题。
查看完整描述

3 回答

?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

语法[e1, e2 .. e3]实际上是语法糖enumFromThenTo e1 e2 e3,它是Enum类型类中的一个函数。


Haskell标准定义了它的语义如下:


对于类型Int和Integer,枚举函数具有以下含义:


序列enumFrom e1是列表[e1,e1 + 1,e1 + 2,…]。

序列enumFromThen e1 e2是列表[e1,e1 + i,e1 + 2i,…],其中增量i为e2 − e1。增量可以是零或负数。如果增量为零,则所有列表元素都相同。

序列enumFromTo e1 e3是列表[e1,e1 + 1,e1 + 2,…e3]。如果列表是空的e1  >  e3。

序列enumFromThenTo e1 e2 e3是列表[e1,e1 + i,e1 +

  2i,…e3],其中增量i为e2 − e1。如果增量为正或零,则列表在下一个元素大于时终止e3; 如果列表是空的e1  >  e3。如果增量为负,则列表在下一个元素小于时终止  e3; 如果列表是空的e1  <  e3。

这几乎是您所期望的,但是Float和Double实例的定义不同:


对于Float和Double,系列的语义enumFrom由Int上面的规则给出,除了当元素变得大于e3 + i∕2正增量时i,或者当它们变得小于e3 + i∕2负数时,列表终止i。


我不确定这是什么理由,所以我能给你的唯一答案就是这样,因为它在标准中就是这样定义的。


您可以通过使用整数枚举并转换为之Float后来解决此问题。


Prelude> map fromIntegral [1, 3 .. 10] :: [Float]

[1.0,3.0,5.0,7.0,9.0]


查看完整回答
反对 回复 2019-09-03
?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

这样的总和通常也会在省略最后一项时给出错误的结果; 只有在特殊情况下sqrt (1 - 1)才会这样。我再次争辩说明显错误的 NaN比一个听起来不错的订单0不准确的浮点数更不好。 - 要确定这样的东西,使用可能触及域边界的浮动只是从根本上说是错误的方法; 一个应该计算单元格中点,或者仅使用范围语法用于单元间边界,但是分别添加精确的外部边界。

查看完整回答
反对 回复 2019-09-03
  • 3 回答
  • 0 关注
  • 689 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信