球拍 - 创建具有一定限制的水密度功能

时间:2014-09-16 18:22:58

标签: scheme racket

我正在尝试解决以下问题:

  

最近,芬兰人对冰桶及其属性非常好奇。他一直在审查水和冰的密度。事实证明,两种状态下的水密度取决于许多因素,包括温度,大气压力和水的纯度。

     

作为近似值,Finn编写了以下函数来确定水(或冰)的密度,单位为kg / m 3 ,作为温度 t 的函数。摄氏度(-273.15≤ t ≤100):

water-density(t) = ( 999.97 if t ≥ 0 ;
                     916.7  if t < 0 )
     

编写一个消耗整数温度water-density的函数t并生成999.97或916.7,具体取决于t的值。但是,您只能使用在第1单元结束时给出的Racket功能。

     

您可以使用define和数学函数,但 condif,列表,递归,布尔值或其他我们将要访问的内容后来在课程中。具体而言,您可以使用本页第1.5节中的任何功能:http://docs.racket-lang.org/htdp-langs/beginner.html,但以下功能除外:允许:sgnfloorceilinground

这是我到目前为止所做的:

(define (water-density t)
  (+ (* (/ (min t 0) (min t -0.000001)) -83.27) 999.97))

只要给定温度不在-0.000001和0之间,此代码就可以正常工作,但它不适用于该范围之间的温度。我该怎么做才能避免这个问题?除以零是我在这里遇到的最大问题。

1 个答案:

答案 0 :(得分:3)

这是一种有趣的教学编程方式,我觉得这个课程将来会导致更多的StackOverflow问题出现,但你可以通过组合{{1}来实现}和max创建一个返回1或0的函数,具体取决于其输入是否为负数:

min

此函数采用一个数字,使用(define (negative->boolint n)) (- 0 (min 0 (max (inexact->exact (floor n)) -1)))) 将其向下舍入,然后(inexact->exact (floor n))max&#34;&#34;的组合。数字介于-1和0之间,然后从1中减去结果。由于转换为整数后数字永远不会介于-1和0之间,因此边界只会导致0为正数,零和-1为负数。减法部分表示函数返回所有正数的零min和零,并返回所有负数的(- 0 0)。通过将此函数的结果与某些算术相结合,您可以获得所需的行为:

(- 1 -1)

如果(define (water-density t) (- 999.97 (* 83.27 (negative->boolint t)))) 为正数或零,那么t的结果将为零。否则,将减去两个密度的差异,从而得到正确的结果。

这是有效的,因为它只是利用(* 83.27 (negative->boolint t))max的内置条件功能来进行条件运算。对于minround或其他具有条件逻辑的语句,您可能会遇到一定程度的hackery。

修改

道歉,我错过了关于无法使用舍入功能的部分问题。但是,您希望通过使用两个基本函数来模拟条件:absabs,但仍然可行。从expt获取条件非常简单,您可以将数字除以其绝对值来得到它的符号。您需要abs的原因是因为它允许您通过expt的零问题绕过除法,因为abs对于所有正数为0,对于零为1,对于负数未定义。我们可以使用它来创建(expt 0 x)函数:

zero->boolint

有了这个,我们可以将其结果添加到分子和分母,以便在(define (zero->boolint x) (expt 0 (abs x))) 中绕过除零。由于这导致除以零的情况返回1,我们现在有一个(/ x (abs x))函数:

nonnegative->boolint

内部除法负责将数字除以其绝对值,以便为负数返回-1,为正数和零返回1。外部加1然后除以2将其变为0表示负数,1表示正数和0表示。为了获得(define (nonnegative->boolint x) (/ (+ 1 (/ (+ (zero->boolint x) x) (+ (zero->boolint x) (abs x)))) 2)) 函数,我们只需要进行某种negative->boolint操作 - 对于not为1,对true为0只是减去该值从1.我们可以仅基于falsenegative->boolint的条件逻辑定义abs

expt

这与(define (negative->boolint x) (- 1 (nonnegative->boolint x)) 的定义一样正常。另外,请不要在现实代码中执行此操作。无论如何&#34;聪明&#34;它似乎在当时。