简体   繁体   English

球拍-创建具有某些限制的水密度函数

[英]Racket - creating a water density function with certain restrictions

I am attempting to solve the following problem: 我正在尝试解决以下问题:

Lately, Finn has been very curious about buckets of ice water and their properties. 最近,芬恩(Finn)对一桶冰水及其性质非常好奇。 He has been reviewing the density of water and ice. 他一直在审查水和冰的密度。 It turns out the density of water in both states depends on many factors, including the temperature, atmospheric pressure, and the purity of the water. 事实证明,两种状态下的水密度都取决于许多因素,包括温度,大气压和水的纯度。

As an approximation, Finn has written the following function to determine the density of the water (or ice) in kg/m 3 as a function of temperature t in Celsius (−273.15 ≤ t ≤ 100): 作为近似,芬兰写以下函数来确定千克/米3的水的密度(或冰)作为温度t在摄氏的函数(-273.15≤ ≤100):

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

Write a function water-density that consumes an integer temperature t and produces either 999.97 or 916.7, depending on the value of t . 编写一个函数water-density ,该函数消耗一个整数温度t并根据t的值产生999.97或916.7。 However, you may only use the features of Racket given up to the end of Module 1. 但是,您只能使用模块1末尾给出的Racket功能。

You may use define and mathematical functions, but not cond , if , lists, recursion, Booleans, or other things we'll get to later in the course. 您可以使用define和数学函数,但不能使用 condif ,list,递归,布尔值或其他我们将在本课程后面介绍的功能。 Specifically, you may use any of the functions in section 1.5 of this page: http://docs.racket-lang.org/htdp-langs/beginner.html except for the following functions, which are not allowed: sgn , floor , ceiling , round . 具体来说,你可以使用任何的功能在这个页面的第1.5节: http://docs.racket-lang.org/htdp-langs/beginner.html除下列功能,这是不允许的: sgnfloorround ceiling

This is what I have so far: 这是我到目前为止的内容:

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

This code does definitely work as long as the given temperature is not between -0.000001 and 0, but it will not work for temperatures between that range. 只要给定温度不在-0.000001到0之间,此代码就可以正常工作,但对于该范围内的温度将不起作用。 What can I do to avoid this problem? 我应该怎么做才能避免这个问题? Dividing by zero is the biggest problem I have here. 除以零是我在这里遇到的最大问题。

This is a somewhat.... interesting way of going about teaching programming, and I have a feeling this class is going to cause more StackOverflow questions to appear in the future, but you can do it by combining max and min to make a function that returns either 1 or 0 depending on whether its input is negative: 这是一种有点...有趣的方式来进行编程教学,并且我感觉这堂课将来会引起更多的StackOverflow问题,但是您可以通过组合maxmin来实现一个函数根据输入是否为负返回1或0:

(define (negative->boolint n))
  (- 0
     (min 0
          (max (inexact->exact (floor n))
               -1))))

This function takes a number, rounds it down with (inexact->exact (floor n)) , then the combination of max and min "bounds" the number to be between -1 and 0, then subtracts that result from 1. Since after conversion to an integer the number can never be between -1 and 0, the bounding just results in 0 for positives and zero and -1 negatives. 此函数接受一个数字,将其四舍五入为(inexact->exact (floor n)) ,然后将maxmin的组合“限制”该数字为-1和0之间,然后从1中减去该结果。转换为整数,该数字永远不能在-1和0之间,边界只会导致正数为0,负数为-1。 The subtraction part means the function returns (- 0 0) for all positive numbers and zero and returns (- 1 -1) for all negative numbers. 减法部分意味着该函数对所有正数返回零(- 0 0) ,对所有负数返回(- 1 -1) By combining the result of this function with some arithmetic, you can get the behavior you want: 通过将此函数的结果与某种算术结合起来,您可以获得所需的行为:

(define (water-density t)
  (- 999.97
     (* 83.27
        (negative->boolint t))))

If t is positive or zero, then the result of (* 83.27 (negative->boolint t)) will just be zero. 如果t为正或零,那么(* 83.27 (negative->boolint t))将为零。 Otherwise, the difference of the two densities will be subtracted, giving you the correct result. 否则,将减去两个密度的差,从而得出正确的结果。

This works because it's just taking advantage of max and min 's built-in conditional functionality to do conditional arithmetic. 之所以可行,是因为它只是利用maxmin的内置条件功能来进行条件运算。 You could probably achieve the same with some level of hackery for round or abs or other statements that have conditional logic. 对于具有roundabs或其他具有条件逻辑的语句,使用某种级别的骇客可能会达到相同的目的。

EDIT 编辑

My apologies, I missed the part of your question about not being able to use the rounding functions. 抱歉,我错过了您无法使用舍入功能的问题。 Want you want is still doable however, by using two base functions for simulating conditionals: abs and expt . 但是,通过使用两个用于模拟条件的基本函数可以使您想要的东西仍然可行: absexpt Getting conditionals from abs is fairly straightforward, you can divide a number by its absolute value to get it's sign. abs获取条件是非常简单的,您可以将数字除以绝对值以获得符号。 The reason you need expt is because it lets you get around the division by zero issue with abs , because (expt 0 x) is 0 for all positive numbers, 1 for zero, and undefined for negative numbers. 需要expt的原因是因为它使您可以解决abs的除零问题,因为(expt 0 x)对于所有正数均为0,对于零为1,对于负数未定义。 We can use this to make a zero->boolint function: 我们可以使用它来创建zero->boolint函数:

(define (zero->boolint x)
  (expt 0 (abs x)))

With this, we can add its result to the numerator and denominator to get around division by zero in (/ x (abs x)) . 这样,我们就可以将其结果添加到分子和分母中,从而在(/ x (abs x))被零除。 Since this causes the division by zero case to return 1, we now have a nonnegative->boolint function: 由于这会导致被零除的情况返回1,因此我们现在有了nonnegative->boolint函数:

(define (nonnegative->boolint x)
  (/ (+ 1
        (/ (+ (zero->boolint x) x)
           (+ (zero->boolint x) (abs x))))
     2))

The inner division takes care of dividing a number by its absolute value to return -1 for negatives and 1 for positives and zero. 内部除法将数字除以其绝对值,以使负数返回-1,正数返回零,并返回1。 The outer addition by 1 and then division by 2 turns this into 0 for negatives and 1 for positives and zero. 外部加1,然后除以2,则负数变为0,正数变为1,零变​​为1。 In order to get a negative->boolint function, we just need some sort of not operation - which in the case of 1 for true and 0 for false is just subtracting the value from 1. So we can define negative->boolint based on only the conditional logic of abs and expt as: 为了得到一个negative->boolint功能,我们只需要某种not运行-这在1的情况下, true和0的false只是从1减去值因此,我们可以定义negative->boolint基于只有absexpt的条件逻辑为:

(define (negative->boolint x)
  (- 1 (nonnegative->boolint x))

This works as expected with the definition of water-density . 这与water-density的定义一样工作。 Also, please don't ever do this in real world code. 另外,请不要在实际代码中执行此操作。 No matter how "clever" it may seem at the time. 无论在当时看起来多么“聪明”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM