2

我目前正在搞乱“如何设计程序”——使用方案/球拍;我在 Scheme 的 R5RS 版本中遇到了一个非常特殊的功能。

在进行简单的减法运算时,尽管使用具有小数点精度的值,但答案与预期的结果相差甚远。

例如; 给定以下减法运算:

(- 5.00 4.90)
=> 0.09999999999999965

什么时候肯定应该期待干净的 0.10?整数减法按预期工作;

> (- 5 4)
 => 1
> (- 5 4.9)
 => 0.09999999999999965

以练习 3.1.1为例:

下一步是为每个功能制作示例。确定有多少观众能够以 3.00 美元、4.00 美元和 5.00 美元的票价购买演出。使用这些示例制定一个通用规则,说明如何根据票价计算参加者人数。如有需要,请编造更多示例。

示例中的规则是票价每减少 0.10 美元,就会有 15 人参加。所以像这样的快速功能会起作用..

(define (attendees ticket-price)
  (+ 120 (* (/ (- 5.00 ticket-price) 0.10) 15)))

但是,这会返回(相当烦人的)..

> (attendance 4.90)
 => 134.99999999999994

因此,在尝试了教科书中的(几乎相同的)解决方案之后..

(define (attendance price)
  (+ (* (/ 15 .10) (- 5.00 price))
    120))

我得到了完全相同的错误。这是我的本地系统特有的吗?我很好奇——实际上我可以简单地使用某种形式的舍入来纠正这个问题;但我宁愿知道为什么它首先发生!

除此之外,我建议任何对 Lisp 感兴趣的人看看 HTDP。从略读来看,它似乎是一个相当温和的文本,非常实用。我确实喜欢 SICP——但这更像是一个长期的事情;我似乎花了好几天的时间阅读,然后练习,然后赶上在线讲座。HTDP 似乎更像是“哦,我有 15 分钟的空闲时间 - 我会看看 HTDP ”。

4

2 回答 2

6

浮点数并不总是存储为您期望的确切值。参见例如The Perils of Floating Point

如果您想要精确计算,您可以在您的情况下使用整数算术,将值存储为美分而不是美元。

(define (attendees ticket-price-cents)
  (+ 12000 (* (/ (- 500 ticket-price-cents) 10) 1500)))
于 2012-12-03T22:46:27.757 回答
5

除了先前的(正确的)答案之外:您真正应该问的问题是:“为什么这不会发生在其他语言级别?” 答案是:许多其他语言级别将 5.03 解释为精确数字(百分之五和百分之三)而不是浮点数。

仅供参考!

于 2012-12-03T23:15:22.967 回答