Issue 8909 in go: math: math.Hypot returns incorrect result

14 views
Skip to first unread message

g...@googlecode.com

unread,
Oct 8, 2014, 12:28:18 PM10/8/14
to golan...@googlegroups.com
Status: New
Owner: ----

New issue 8909 by lukeusma...@gmail.com: math: math.Hypot returns incorrect
result
https://code.google.com/p/go/issues/detail?id=8909

Before filing a bug, please check whether it has been fixed since the
latest release. Search the issue tracker and check that you're running the
latest version of Go:

Run "go version" and compare against
http://golang.org/doc/devel/release.html If a newer version of Go exists,
install it and retry what you did to reproduce the problem.

Thanks.

What does 'go version' print?
go version go1.3.3 linux/amd64

What steps reproduce the problem?
Compute the function math.Hypot(0.08879849107482636, -0.07597714093596328)

If possible, include a link to a program on play.golang.org.
http://play.golang.org/p/4jsrWchSln

What happened?
The value 0.11686615404799307 was returned

What should have happened instead?
It should have returned the correct value of 0.11686615404799305

Please provide any additional information below.

Java and Python both give the result 0.11686615404799305
I would suggest that this is a problem with square root accuracy/precision.



--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings

g...@googlecode.com

unread,
Oct 8, 2014, 2:28:32 PM10/8/14
to golan...@googlegroups.com
Updates:
Labels: Repo-Main Release-Go1.5

Comment #1 on issue 8909 by i...@golang.org: math: math.Hypot returns
incorrect result
https://code.google.com/p/go/issues/detail?id=8909

(No comment was entered for this change.)

g...@googlecode.com

unread,
Dec 2, 2014, 2:24:52 PM12/2/14
to golan...@googlegroups.com
Updates:
Status: Accepted

Comment #2 on issue 8909 by joshar...@gmail.com: math: math.Hypot returns
incorrect result
https://code.google.com/p/go/issues/detail?id=8909

Running this through a high precision calculator yields
0.1168661540479930566903, so the Java/Python results do look more accurate.
In the case of Python at least, it is calling through to libc's hypot.

From a quick poke, it looks like when the arguments are close in magnitude
(p <= 2q) and reasonable in size, you get more accurate results from

return math.Sqrt((p-q)*(p-q) + 2*p*q)

than from what we currently use

q = q / p
return p * math.Sqrt(1+q*q)

Cf http://play.golang.org/p/yI4-ENaoB7

Input from someone with expertise would be welcomed.

g...@googlecode.com

unread,
Dec 7, 2014, 8:15:14 AM12/7/14
to golan...@googlegroups.com

Comment #3 on issue 8909 by alb.doni...@gmail.com: math: math.Hypot returns
incorrect result
https://code.google.com/p/go/issues/detail?id=8909

G. W. Stewart in "Matrix Algorithms: Volume 1", SIAM 1998, pages 139 and
144, cited by B. Einarsson
in "Accuracy and Reliability in Scientific Computing", SIAM 2005, page 48,
suggest using

s = p + q
hypot(p, q) = s * math.Sqrt((p/s)*(p/s) + (q/s)*(q/s))

so, scaling with p+q instead of max{|p|, |q|}, because (I cite from the
former)

"If the scale factor s in the algorithm [..] is replaced by max{|a|, |b|},
the results
may be less accurate on a hexadecimal machine. The reason is that the number

sqrt((a/s)^2 + (b/s)^2) [equivalent to our q = q / p; return p *
math.Sqrt(1+q*q); ndr]

is a little bit greater than one [iff min{a,b} is small? I think, ndr] so
that the leading three bits
in its representation are zero."

Scaling with s = a + b returns the correct number in this case:

http://play.golang.org/p/P0GduYlgQ-

and also provides protection against [over|under]flow.

If we don't want to port the (rather complicated) libc hypot(), maybe the
suggested alternative
expression would be a better "simple but good enough" implementation than
the current one.

This claim should be tested, though.
Reply all
Reply to author
Forward
0 new messages