如何对浮子和复合物进行近似结构模式匹配
我已经阅读并理解 flo floating Point Point rough-off rough off jearses 例如:
>>> sum([0.1] * 10) == 1.0
False
>>> 1.1 + 2.2 == 3.3
False
>>> sin(radians(45)) == sqrt(2) / 2
False
i i i还知道如何使用 math.isclose()和 cmath.isclose()。
问题是如何将这些工作应用于Python的匹配/案例语句。我希望这可以工作:
match 1.1 + 2.2:
case 3.3:
print('hit!') # currently, this doesn't match
I've read about and understand floating point round-off issues such as:
>>> sum([0.1] * 10) == 1.0
False
>>> 1.1 + 2.2 == 3.3
False
>>> sin(radians(45)) == sqrt(2) / 2
False
I also know how to work around these issues with math.isclose() and cmath.isclose().
The question is how to apply those work arounds to Python's match/case statement. I would like this to work:
match 1.1 + 2.2:
case 3.3:
print('hit!') # currently, this doesn't match
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解决方案的关键是构建一个包装器,该包装器覆盖
__ eq __
方法并将其替换为近似匹配:它为float值和复杂值创建近似的等价测试:
这是如何在中使用它匹配/案例语句:
此输出:
The key to the solution is to build a wrapper that overrides the
__eq__
method and replaces it with an approximate match:It creates approximate equality tests for both float values and complex values:
Here is how to use it in a match/case statement:
This outputs:
雷蒙德(Raymond)的回答非常奇特和人体工程学,但对于可能更简单的事情来说似乎很魔力。一个更小的版本将只是捕获计算值,并明确检查事物是否“关闭”,例如:
我也建议仅使用
cmath.isclose()
在哪里/何时实际上需要它,使用适当的类型可让您确保代码正在执行您的期望。上面的示例只是用于演示匹配的最小代码,如注释中指出的那样,可以使用传统的 If 语句更容易地实现。冒着脱离原始问题的风险,这是一个更完整的示例:
不确定我在这里是否实际使用
Match
语句,但希望更有代表性!Raymond's answer is very fancy and ergonomic, but seems like a lot of magic for something that could be much simpler. A more minimal version would just be to capture the calculated value and just explicitly check whether the things are "close", e.g.:
I'd also suggest only using
cmath.isclose()
where/when you actually need it, using appropriate types lets you ensure your code is doing what you expect.The above example is just the minimum code used to demonstrate the matching and, as pointed out in the comments, could be more easily implemented using a traditional
if
statement. At the risk of derailing the original question, this is a somewhat more complete example:Not sure if I'd actually use a
match
statement here, but is hopefully more representative!