我正在做 How to Think Like a Computer Scientist 第 5 章中的练习,并正在尝试解决第三个练习:
Write a function
slope(x1, y1, x2, y2)
that returns the slope of the line through the points (x1, y1) and (x2, y2). Be sure your implementation ofslope
can pass the following doctests:def slope(x1, y1, x2, y2): """ >>> slope(5, 3, 4, 2) 1.0 >>> slope(1, 2, 3, 2) 0.0 >>> slope(1, 2, 3, 3) 0.5 >>> slope(2, 4, 1, 2) 2.0 """
这是我想出的代码:
def slope(x1, y1, x2, y2):
"""
>>> slope(5, 3, 4, 2)
1.0
>>> slope(1, 2, 3, 2)
0.0
"""
sy = float(y1 - y2)
sx = float(x1 - x2)
return sy / sx
在第二次文档测试中,我得到的是 -0.0
而不是 0.0
...这很令人困惑,因为我不知道 -0.0
是一件事。我知道我可以使用 abs()
来获取绝对值,但是,如果我确实有应该为负数的参数,它就不起作用。
还知道我可以对结果设置一个条件,以便它使用或不使用绝对值,但我想知道我是否在这里做错了什么。
最佳答案
您可以编写一个 slope()
版本,通过交换 y1 - y2
的顺序,为该 doctest 中的参数返回正 0.0
> 和 x1 - x2
在您的代码中:
def slope(x1, y1, x2, y2):
"""
>>> slope(5, 3, 4, 2)
1.0
>>> slope(1, 2, 3, 2)
0.0
"""
sy = float(y2 - y1)
sx = float(x2 - x1)
return sy / sx
>>> slope(1, 2, 3, 2)
0.0
如果参数颠倒,您仍然会得到 -0.0
:
>>> slope(3, 2, 1, 2)
-0.0
…但是在文档测试之外这不太重要,因为 0.0
和 -0.0
根据定义是相等的。但是,如果您想确保始终返回正零,您可以只 add zero到你的返回值:
def slope(x1, y1, x2, y2):
"""
>>> slope(5, 3, 4, 2)
1.0
>>> slope(1, 2, 3, 2)
0.0
"""
sy = float(y2 - y1)
sx = float(x2 - x1)
return sy / sx + 0 # prevent -0.0
>>> slope(1, 2, 3, 2)
0.0
>>> slope(3, 2, 1, 2)
0.0
“添加正零”技巧是任意的,本质上是神奇的行为,它之所以有效,是因为 IEEE 754 浮点标准规定它必须:
When the sum of two operands with opposite signs (or the difference of two operands with like signs) is exactly zero, the sign of that sum (or difference) shall be +0 in all rounding-direction attributes except roundTowardNegative; under that attribute, the sign of an exact zero sum (or difference) shall be −0. However, x + x = x − (−x) retains the same sign as x even when x is zero.
— IEEE 754, Section 6.3
有关浮点运算中有符号零的更多信息,请访问 What Every Computer Scientist Should Know About Floating-Point Arithmetic .
关于python - 浮点除法返回 -0.0 而不是 0.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49225403/