math: eliminate overflow in Pow(x,y) for large y
The current implementation uses a shift and add loop to compute the product of x's exponent xe and the integer part of y (yi) for yi up to 1<<63. Since xe is an 11-bit exponent, this product can be up to 74-bits and overflow both 32 and 64-bit int. This change checks whether the accumulated exponent will fit in the 11-bit float exponent of the output and breaks out of the loop early if overflow is detected. The current handling of yi >= 1<<63 uses Exp(y * Log(x)) which incorrectly returns Nan for x<0. In addition, for y this large, Exp(y * Log(x)) can be enumerated to only overflow except when x == -1 since the boundary cases computed exactly: Pow(NextAfter(1.0, Inf(1)), 1<<63) == 2.72332... * 10^889 Pow(NextAfter(1.0, Inf(-1)), 1<<63) == 1.91624... * 10^-445 exceed the range of float64. So, the call can be replaced with a simple case statement analgous to y == Inf that correctly handles x < 0 as well. Fixes #7394 Change-Id: I6f50dc951f3693697f9669697599860604323102 Reviewed-on: https://go-review.googlesource.com/48290Reviewed-by: Robert Griesemer <gri@golang.org>
Showing
Please register or sign in to comment