This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Regression in math.hypot
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.9
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: cffk, mark.dickinson, rhettinger, tim.peters
Priority: normal Keywords:

Created on 2021-01-31 22:33 by cffk, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
hypot_bug.py cffk, 2021-01-31 22:33 illustration of bad behavior in math.hypot
Messages (6)
msg386043 - (view) Author: Charles Karney (cffk) Date: 2021-01-31 22:33
It would be nice if math.hypot had the property

If
  0 < y1 < y2
then
  math.hypot(x, y1) <= math.hypot(x, y2)

This is not the case in python3 with

  x  = 0.6102683302836215
  y1 = 0.7906090004346522
  y2 = y1 + 1e-16

python2's implementation of math.hypot is OK with these inputs.
msg386047 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2021-01-31 23:06
Thanks for the report.  This is fixed in Python 3.10 where your script outputs:   [1.1102230246251565e-16, 1.1102230246251565e-16]

There isn't much that can be done about it for Python 3.9.
msg386048 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2021-01-31 23:16
I agree this doesn't occur in 3.10, but think Raymond pasted wrong outputs. Here:

Python 3.10.0a4+ (heads/master:64fc105b2d, Jan 28 2021, 15:31:11)
[MSC v.1928 64 bit (AMD64)] on win32
>>> x  = 0.6102683302836215
>>> y1 = 0.7906090004346522
>>> y2 = y1 + 1e-16
>>> from math import hypot
>>> hypot(x, y1)
0.998744224772008
>>> hypot(x, y2)
0.9987442247720081

Those both appear to be the results "as if" computed to infinite precision and then correctly rounded back to Python's float precision.
msg386049 - (view) Author: Charles Karney (cffk) Date: 2021-01-31 23:39
Many thanks!  Was the 3.9 version of hypot introduced in 3.0?  I'm fixing my code to call sqrt(x**2 + y**2) if necessary and I'd like to know what range of versions this version should apply for.
msg386050 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2021-02-01 00:01
>  I'd like to know what range of versions this version should apply for.

Only 3.8 and 3.9.

Prior to that, we used the C compiler's hypot() which tended to be very good but was implementation dependent, only covered the two argument case, and made no particular guarantees about accuracy, commutativity, or monotonicity.
msg386051 - (view) Author: Charles Karney (cffk) Date: 2021-02-01 02:59
Thanks for the info.
History
Date User Action Args
2022-04-11 14:59:40adminsetgithub: 87254
2021-02-01 20:13:20mark.dickinsonsetnosy: + mark.dickinson
2021-02-01 02:59:47cffksetmessages: + msg386051
2021-02-01 00:01:16rhettingersetmessages: + msg386050
2021-01-31 23:39:36cffksetmessages: + msg386049
2021-01-31 23:16:38tim.peterssetnosy: + tim.peters
messages: + msg386048
2021-01-31 23:06:26rhettingersetstatus: open -> closed

assignee: rhettinger

nosy: + rhettinger
messages: + msg386047
resolution: out of date
stage: resolved
2021-01-31 22:33:45cffkcreate