我正在尝试解决以下问题:
最近,芬兰人对冰桶及其属性非常好奇。他一直在审查水和冰的密度。事实证明,两种状态下的水密度取决于许多因素,包括温度,大气压力和水的纯度。
作为近似值,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
和数学函数,但不cond
,if
,列表,递归,布尔值或其他我们将要访问的内容后来在课程中。具体而言,您可以使用本页第1.5节中的任何功能:http://docs.racket-lang.org/htdp-langs/beginner.html,但以下功能除外:不允许:sgn
,floor
,ceiling
,round
。
这是我到目前为止所做的:
(define (water-density t)
(+ (* (/ (min t 0) (min t -0.000001)) -83.27) 999.97))
只要给定温度不在-0.000001和0之间,此代码就可以正常工作,但它不适用于该范围之间的温度。我该怎么做才能避免这个问题?除以零是我在这里遇到的最大问题。
答案 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
的内置条件功能来进行条件运算。对于min
或round
或其他具有条件逻辑的语句,您可能会遇到一定程度的hackery。
道歉,我错过了关于无法使用舍入功能的部分问题。但是,您希望通过使用两个基本函数来模拟条件:abs
和abs
,但仍然可行。从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.我们可以仅基于false
和negative->boolint
的条件逻辑定义abs
:
expt
这与(define (negative->boolint x)
(- 1 (nonnegative->boolint x))
的定义一样正常。另外,请不要在现实代码中执行此操作。无论如何&#34;聪明&#34;它似乎在当时。